public class Passenger {
int id;
int arrivalTime;
int startFloor;
int targetFloor;
int pickupTime = -1;
int deliveryTime = -1;
boolean pickedUp = false;
int pickedUpBy = -1;
public Passenger(int id, int arrivalTime, int startFloor, int targetFloor) {
this.id = id;
this.arrivalTime = arrivalTime;
this.startFloor = startFloor;
this.targetFloor = targetFloor;
}
public int getDirection() {
return Integer.compare(targetFloor, startFloor);
}
public int getWaitingTime() {
return pickupTime - arrivalTime;
}
public int getTotalTime() {
return deliveryTime - arrivalTime;
}
@Override
public String toString() {
return "乘客" + id + " [" + startFloor + "→" + targetFloor + "]";
}
}
import java.util.*;
import java.util.stream.Collectors;
public class Elevator {
public enum State { IDLE, MOVING, STOPPED }
// 基本属性
int id;
int currentFloor = 1;
State state = State.IDLE;
int passengers = 0;
int capacity = 8;
// 时间参数
int moveTime = 2; // 移动一层所需时间(秒)
int stopTime = 3; // 停靠时间(秒)
// 运行数据
List<Passenger> onboard = new ArrayList<>();
int timeCounter = 0;
// 调度相关
int destinationFloor = -1;
int direction = 0;
Passenger currentTargetPassenger = null;
Set<Integer> ignoredPassengerIds = new HashSet<>();
public Elevator(int id) {
this.id = id;
}
/**
* 设置目标乘客
*/
public void setTargetPassenger(Passenger p, List<Elevator> allElevators) {
if (p == null) return;
// 清除旧目标的忽略标记
if (currentTargetPassenger != null) {
allElevators.forEach(e -> e.ignoredPassengerIds.remove(currentTargetPassenger.id));
}
this.currentTargetPassenger = p;
destinationFloor = p.startFloor;
direction = Integer.compare(destinationFloor, currentFloor);
state = State.MOVING;
// 通知其他电梯忽略此乘客
allElevators.stream()
.filter(e -> e != this)
.forEach(e -> e.ignoredPassengerIds.add(p.id));
}
/**
* 更新目标楼层
*/
public void updateDestination() {
// 优先级1: 当前目标乘客
if (currentTargetPassenger != null) {
destinationFloor = currentTargetPassenger.startFloor;
return;
}
// 优先级2: 电梯内乘客的目标楼层
if (!onboard.isEmpty()) {
// 找到最近的乘客目标楼层
int closestFloor = onboard.get(0).targetFloor;
int minDistance = Math.abs(closestFloor - currentFloor);
for (Passenger p : onboard) {
int distance = Math.abs(p.targetFloor - currentFloor);
if (distance < minDistance) {
minDistance = distance;
closestFloor = p.targetFloor;
}
}
destinationFloor = closestFloor;
direction = Integer.compare(destinationFloor, currentFloor);
return;
}
// 无目标
destinationFloor = -1;
direction = 0;
state = State.IDLE;
}
/**
* 添加乘客到电梯
*/
public void addPassenger(Passenger p, int currentTime, List<Elevator> allElevators) {
if (passengers >= capacity) return;
onboard.add(p);
passengers++;
p.pickupTime = currentTime;
p.pickedUp = true;
p.pickedUpBy = this.id;
// 更新目的地
updateDestination();
// 从其他电梯的计划中移除该乘客
allElevators.stream()
.filter(e -> e != this)
.forEach(e -> {
if (e.currentTargetPassenger == p) {
e.currentTargetPassenger = null;
e.updateDestination();
}
});
}
/**
* 每秒更新电梯状态
*/
public void updateState(int currentTime,
List<Passenger> upWaiting,
List<Passenger> downWaiting,
List<Elevator> allElevators) {
timeCounter++;
switch (state) {
case IDLE:
// 空闲状态不执行操作
break;
case MOVING:
if (timeCounter >= moveTime) {
currentFloor += direction;
timeCounter = 0;
// 检查是否到达目标楼层
if (currentFloor == destinationFloor) {
state = State.STOPPED;
}
// 检查是否有顺路乘客
else if (checkForPickups(currentFloor, upWaiting, downWaiting)) {
state = State.STOPPED;
}
}
break;
case STOPPED:
if (timeCounter >= stopTime) {
state = State.MOVING;
timeCounter = 0;
updateDestination();
}
break;
}
}
/**
* 处理停靠点上下客
*/
public void processStop(int currentTime,
List<Passenger> upWaiting,
List<Passenger> downWaiting,
List<Elevator> allElevators) {
// 1. 下客
List<Passenger> toUnload = new ArrayList<>();
for (Passenger p : onboard) {
if (p.targetFloor == currentFloor) {
toUnload.add(p);
p.deliveryTime = currentTime;
}
}
onboard.removeAll(toUnload);
passengers -= toUnload.size();
// 2. 上客 - 目标乘客优先
if (currentTargetPassenger != null &&
currentTargetPassenger.startFloor == currentFloor &&
!currentTargetPassenger.pickedUp) {
addPassenger(currentTargetPassenger, currentTime, allElevators);
currentTargetPassenger = null;
}
// 3. 上客 - 顺路乘客
List<Passenger> directionPassengers = direction > 0 ? upWaiting : downWaiting;
Iterator<Passenger> it = directionPassengers.iterator();
while (it.hasNext() && passengers < capacity) {
Passenger p = it.next();
if (p.startFloor == currentFloor &&
!ignoredPassengerIds.contains(p.id) &&
!p.pickedUp) {
addPassenger(p, currentTime, allElevators);
it.remove();
}
}
// 更新目的地
updateDestination();
}
// 检查当前楼层是否有可接载的乘客
private boolean checkForPickups(int floor,
List<Passenger> upWaiting,
List<Passenger> downWaiting) {
List<Passenger> directionPassengers = direction > 0 ? upWaiting : downWaiting;
for (Passenger p : directionPassengers) {
if (p.startFloor == floor &&
!ignoredPassengerIds.contains(p.id) &&
!p.pickedUp) {
return true;
}
}
return false;
}
// 获取状态摘要
public String getStatus() {
String stateStr = state == State.IDLE ? "空闲" :
state == State.MOVING ? "移动中" : "停靠中";
String dirStr = direction > 0 ? "↑" : direction < 0 ? "↓" : "";
String targetStr = destinationFloor > 0 ? destinationFloor + "楼" : "无";
return String.format("电梯%d [%d楼] %s %s 乘客:%d 目标:%s",
id, currentFloor, stateStr, dirStr, passengers, targetStr);
}
}
import java.util.*;
public class ElevatorSimulation {
// 系统配置
static final int FLOORS = 8;
static final int SIMULATION_TIME = 50; // 模拟50秒
static final int PASSENGER_RATE = 5; // 每5秒生成一个乘客
static final int PASSENGER_COUNT = 10; // 共生成10名乘客
public static void main(String[] args) {
// 初始化两部电梯
List<Elevator> elevators = Arrays.asList(
new Elevator(1),
new Elevator(2)
);
// 乘客队列
List<Passenger> upWaiting = new ArrayList<>();
List<Passenger> downWaiting = new ArrayList<>();
List<Passenger> allPassengers = new ArrayList<>();
// 初始化随机数生成器
Random rand = new Random();
int passengerId = 1;
System.out.println("===== 电梯模拟系统 =====");
System.out.println("模拟时长: " + SIMULATION_TIME + "秒");
System.out.println("乘客生成: 每" + PASSENGER_RATE + "秒一个,共" + PASSENGER_COUNT + "名");
System.out.println("电梯数量: " + elevators.size() + "部");
System.out.println("=".repeat(40));
// 主模拟循环
for (int time = 0; time < SIMULATION_TIME; time++) {
System.out.println("\n--- 时间: " + time + "秒 ---");
// 1. 每5秒生成一个新乘客(直到生成10名)
if (time % PASSENGER_RATE == 0 && passengerId <= PASSENGER_COUNT) {
int start = rand.nextInt(FLOORS) + 1;
int target;
do {
target = rand.nextInt(FLOORS) + 1;
} while (target == start);
Passenger p = new Passenger(passengerId++, time, start, target);
allPassengers.add(p);
// 按方向添加到队列
if (p.getDirection() > 0) {
upWaiting.add(p);
System.out.println("新乘客: " + p + " ↑ (上行)");
} else {
downWaiting.add(p);
System.out.println("新乘客: " + p + " ↓ (下行)");
}
}
// 2. 更新电梯状态
for (Elevator elevator : elevators) {
elevator.updateState(time, upWaiting, downWaiting, elevators);
// 处理停靠状态
if (elevator.state == Elevator.State.STOPPED) {
elevator.processStop(time, upWaiting, downWaiting, elevators);
}
// 显示电梯状态
System.out.println(elevator.getStatus());
}
// 3. 解决电梯间冲突
resolveConflicts(elevators, time);
// 4. 分配空闲电梯
assignIdleElevators(elevators, upWaiting, downWaiting, time);
// 5. 显示等待队列
System.out.println("等待乘客: ↑" + upWaiting.size() + " ↓" + downWaiting.size());
}
// 6. 输出最终统计
printStatistics(allPassengers);
}
/**
* 解决电梯间目标冲突
*/
static void resolveConflicts(List<Elevator> elevators, int currentTime) {
// 检测目标乘客冲突
Map<Integer, List<Elevator>> targetMap = new HashMap<>();
for (Elevator e : elevators) {
if (e.currentTargetPassenger != null) {
int passengerId = e.currentTargetPassenger.id;
targetMap.computeIfAbsent(passengerId, k -> new ArrayList<>()).add(e);
}
}
// 解决冲突:每个乘客只分配给最近的电梯
for (Map.Entry<Integer, List<Elevator>> entry : targetMap.entrySet()) {
if (entry.getValue().size() > 1) {
int passengerId = entry.getKey();
List<Elevator> conflicting = entry.getValue();
// 找到最近的电梯
Elevator closest = null;
int minDistance = Integer.MAX_VALUE;
for (Elevator e : conflicting) {
int distance = Math.abs(e.currentFloor - e.currentTargetPassenger.startFloor);
if (distance < minDistance) {
minDistance = distance;
closest = e;
}
}
// 其他电梯取消目标
for (Elevator e : conflicting) {
if (e != closest) {
e.currentTargetPassenger = null;
e.updateDestination();
System.out.println("冲突解决: 电梯" + e.id + " 放弃乘客" + passengerId);
}
}
}
}
}
/**
* 为所有空闲电梯分配任务
*/
static void assignIdleElevators(List<Elevator> elevators,
List<Passenger> upWaiting,
List<Passenger> downWaiting,
int currentTime) {
// 获取所有空闲电梯
List<Elevator> idleElevators = new ArrayList<>();
for (Elevator e : elevators) {
if (e.state == Elevator.State.IDLE) {
idleElevators.add(e);
}
}
if (idleElevators.isEmpty()) return;
// 合并等待乘客
List<Passenger> allWaiting = new ArrayList<>();
allWaiting.addAll(upWaiting);
allWaiting.addAll(downWaiting);
// 过滤已被接走的乘客
allWaiting.removeIf(p -> p.pickedUp);
if (allWaiting.isEmpty()) return;
// 为每个空闲电梯分配最近的乘客
for (Elevator e : idleElevators) {
// 查找最近的未分配乘客
Passenger closest = null;
int minDistance = Integer.MAX_VALUE;
for (Passenger p : allWaiting) {
int distance = Math.abs(p.startFloor - e.currentFloor);
if (distance < minDistance) {
minDistance = distance;
closest = p;
}
}
if (closest != null) {
e.setTargetPassenger(closest, elevators);
allWaiting.remove(closest);
System.out.println("分配: 电梯" + e.id + " → 乘客" + closest.id);
}
}
}
/**
* 输出统计结果
*/
static void printStatistics(List<Passenger> passengers) {
System.out.println("\n===== 模拟结果 =====");
System.out.println("乘客总数: " + passengers.size());
int completed = 0;
int totalWaitingTime = 0;
int maxWaitingTime = 0;
int totalTravelTime = 0;
int maxTravelTime = 0;
for (Passenger p : passengers) {
if (p.deliveryTime != -1) {
completed++;
int waitingTime = p.getWaitingTime();
totalWaitingTime += waitingTime;
if (waitingTime > maxWaitingTime) maxWaitingTime = waitingTime;
int travelTime = p.getTotalTime();
totalTravelTime += travelTime;
if (travelTime > maxTravelTime) maxTravelTime = travelTime;
}
}
System.out.println("完成运输: " + completed + " 人 (" +
(completed * 100 / passengers.size()) + "%)");
if (completed > 0) {
System.out.println("平均等待时间: " + (totalWaitingTime / completed) + "秒");
System.out.println("最长等待时间: " + maxWaitingTime + "秒");
System.out.println("平均运输时间: " + (totalTravelTime / completed) + "秒");
System.out.println("最长运输时间: " + maxTravelTime + "秒");
}
// 显示未完成乘客
List<Passenger> unfinished = passengers.stream()
.filter(p -> p.deliveryTime == -1)
.toList();
if (!unfinished.isEmpty()) {
System.out.println("\n未完成乘客:");
for (Passenger p : unfinished) {
String status = p.pickedUp ? "接载中" : "等待中";
System.out.println("乘客" + p.id + ": " + status + " (等待时间: " + (50 - p.arrivalTime) + "秒)");
}
}
}
}
乘客生成的逻辑是什么
public class ElevatorSimulation {
// 系统配置
static final int FLOORS = 8;
static final int SIMULATION_TIME = 50; // 模拟50秒
static final int PASSENGER_RATE = 5; // 每5秒生成一个乘客
static final int PASSENGER_COUNT = 10; // 共生成10名乘客
public static void main(String[] args) {
// 初始化两部电梯
List<Elevator> elevators = Arrays.asList(
new Elevator(1),
new Elevator(2)
);
// 乘客队列
List<Passenger> upWaiting = new ArrayList<>();
List<Passenger> downWaiting = new ArrayList<>();
List<Passenger> allPassengers = new ArrayList<>();
// 初始化随机数生成器
Random rand = new Random();
int passengerId = 1;
System.out.println("===== 电梯模拟系统 =====");
System.out.println("模拟时长: " + SIMULATION_TIME + "秒");
System.out.println("乘客生成: 每" + PASSENGER_RATE + "秒一个,共" + PASSENGER_COUNT + "名");
System.out.println("电梯数量: " + elevators.size() + "部");
System.out.println("=".repeat(40));
// 主模拟循环
for (int time = 0; time < SIMULATION_TIME; time++) {
System.out.println("\n--- 时间: " + time + "秒 ---");
// 1. 每5秒生成一个新乘客(直到生成10名)
if (time % PASSENGER_RATE == 0 && passengerId <= PASSENGER_COUNT) {
int start = rand.nextInt(FLOORS) + 1;
int target;
do {
target = rand.nextInt(FLOORS) + 1;
} while (target == start);
Passenger p = new Passenger(passengerId++, time, start, target);
allPassengers.add(p);
// 按方向添加到队列
if (p.getDirection() > 0) {
upWaiting.add(p);
System.out.println("新乘客: " + p + " ↑ (上行)");
} else {
downWaiting.add(p);
System.out.println("新乘客: " + p + " ↓ (下行)");
}
}
// 2. 更新电梯状态
for (Elevator elevator : elevators) {
elevator.updateState(time, upWaiting, downWaiting, elevators);
// 处理停靠状态
if (elevator.state == Elevator.State.STOPPED) {
elevator.processStop(time, upWaiting, downWaiting, elevators);
}
// 显示电梯状态
System.out.println(elevator.getStatus());
}
// 3. 解决电梯间冲突
resolveConflicts(elevators, time);
// 4. 分配空闲电梯
assignIdleElevators(elevators, upWaiting, downWaiting, time);
// 5. 显示等待队列
System.out.println("等待乘客: ↑" + upWaiting.size() + " ↓" + downWaiting.size());
}
// 6. 输出最终统计
printStatistics(allPassengers);
}
/**
* 解决电梯间目标冲突
*/
static void resolveConflicts(List<Elevator> elevators, int currentTime) {
// 检测目标乘客冲突
Map<Integer, List<Elevator>> targetMap = new HashMap<>();
for (Elevator e : elevators) {
if (e.currentTargetPassenger != null) {
int passengerId = e.currentTargetPassenger.id;
targetMap.computeIfAbsent(passengerId, k -> new ArrayList<>()).add(e);
}
}
// 解决冲突:每个乘客只分配给最近的电梯
for (Map.Entry<Integer, List<Elevator>> entry : targetMap.entrySet()) {
if (entry.getValue().size() > 1) {
int passengerId = entry.getKey();
List<Elevator> conflicting = entry.getValue();
// 找到最近的电梯
Elevator closest = null;
int minDistance = Integer.MAX_VALUE;
for (Elevator e : conflicting) {
int distance = Math.abs(e.currentFloor - e.currentTargetPassenger.startFloor);
if (distance < minDistance) {
minDistance = distance;
closest = e;
}
}
// 其他电梯取消目标
for (Elevator e : conflicting) {
if (e != closest) {
e.currentTargetPassenger = null;
e.updateDestination();
System.out.println("冲突解决: 电梯" + e.id + " 放弃乘客" + passengerId);
}
}
}
}
}
/**
* 为所有空闲电梯分配任务
*/
static void assignIdleElevators(List<Elevator> elevators,
List<Passenger> upWaiting,
List<Passenger> downWaiting,
int currentTime) {
// 获取所有空闲电梯
List<Elevator> idleElevators = new ArrayList<>();
for (Elevator e : elevators) {
if (e.state == Elevator.State.IDLE) {
idleElevators.add(e);
}
}
if (idleElevators.isEmpty()) return;
// 合并等待乘客
List<Passenger> allWaiting = new ArrayList<>();
allWaiting.addAll(upWaiting);
allWaiting.addAll(downWaiting);
// 过滤已被接走的乘客
allWaiting.removeIf(p -> p.pickedUp);
if (allWaiting.isEmpty()) return;
// 为每个空闲电梯分配最近的乘客
for (Elevator e : idleElevators) {
// 查找最近的未分配乘客
Passenger closest = null;
int minDistance = Integer.MAX_VALUE;
for (Passenger p : allWaiting) {
int distance = Math.abs(p.startFloor - e.currentFloor);
if (distance < minDistance) {
minDistance = distance;
closest = p;
}
}
if (closest != null) {
e.setTargetPassenger(closest, elevators);
allWaiting.remove(closest);
System.out.println("分配: 电梯" + e.id + " → 乘客" + closest.id);
}
}
}
/**
* 输出统计结果
*/
static void printStatistics(List<Passenger> passengers) {
System.out.println("\n===== 模拟结果 =====");
System.out.println("乘客总数: " + passengers.size());
int completed = 0;
int totalWaitingTime = 0;
int maxWaitingTime = 0;
int totalTravelTime = 0;
int maxTravelTime = 0;
for (Passenger p : passengers) {
if (p.deliveryTime != -1) {
completed++;
int waitingTime = p.getWaitingTime();
totalWaitingTime += waitingTime;
if (waitingTime > maxWaitingTime) maxWaitingTime = waitingTime;
int travelTime = p.getTotalTime();
totalTravelTime += travelTime;
if (travelTime > maxTravelTime) maxTravelTime = travelTime;
}
}
System.out.println("完成运输: " + completed + " 人 (" +
(completed * 100 / passengers.size()) + "%)");
if (completed > 0) {
System.out.println("平均等待时间: " + (totalWaitingTime / completed) + "秒");
System.out.println("最长等待时间: " + maxWaitingTime + "秒");
System.out.println("平均运输时间: " + (totalTravelTime / completed) + "秒");
System.out.println("最长运输时间: " + maxTravelTime + "秒");
}
// 显示未完成乘客
List<Passenger> unfinished = passengers.stream()
.filter(p -> p.deliveryTime == -1)
.toList();
if (!unfinished.isEmpty()) {
System.out.println("\n未完成乘客:");
for (Passenger p : unfinished) {
String status = p.pickedUp ? "接载中" : "等待中";
System.out.println("乘客" + p.id + ": " + status + " (等待时间: " + (50 - p.arrivalTime) + "秒)");
}
}
}
}
最新发布