2021/05/19 1008 Elevator (20 分)

楼层爬升算法
本文介绍了一个简单的算法,用于计算从当前楼层移动到一系列指定楼层所需的总时间。算法考虑了向上爬楼和向下行走的不同时间成本。
#include<stdio.h>
int main()
{
	int this_floor=0; //需要从该层去到目标楼层
	int next_floor;
	int n,i,sumtime=0;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&next_floor);
		if(next_floor>this_floor)   //往高层爬 
		{
			sumtime+=(next_floor-this_floor)*6;
		}
		else  //往低处走 
		{
			sumtime+=(this_floor-next_floor)*4;
		}
		sumtime+=5;
		this_floor=next_floor; //更新现楼层 
	}
	printf("%d",sumtime); 
	return 0;
}

/* * module_mow.h * * Created on: Feb 19, 2025 * Author: XWM */ #ifndef MODULE_MODULE_MOW_MODULE_MOW_H_ #define MODULE_MODULE_MOW_MODULE_MOW_H_ #include "main.h" #include <stdint.h> #include <stdbool.h> #define MOW_SWITCH (1) /* 割草模块编译开关 */ #if MOW_SWITCH /* 割草轮转一圈2脉冲 */ #define GRASS_CIRCLE_PULSE (12)//2 // 根据速度偏差,结算pwm 脉宽,从而到速度的控制 // 主要以P参数调节为主 // i参数与 d 参数限制了,只做补偿作用,没有用到累积称态作用 #define GRASS_DEAD_ZONE (15.001f) // 速度环死区(单位:转/钟),这个度以下不再调节 #define GRASS_INTEGRAL_ERR (255.0f) // 积离时对应的误差范围,防止超调 #define GRASS_INTEGRAL_LIMIT (1280.0f) // 积范围限定防止积饱和,乘以pid.i参数不得超过255, /* HALL消抖时间 单位ms */ #define ELEVATOR_HALL_PRESS_RELEASE_TIMER (20) /* 堵转ADC值 */ #define ELEVATOR_LOCKED_ROTOR_ADC (200) /* 堵转多长时间进入工作异常 单位s */ #define ELEVATOR_LOCKED_ROTOR_TIMER (10 * 1000) /* 工作超时时间 单位s */ #define ELEVATOR_OVERTIME (17 * 1000) /* 在原点停留的时间 单位ms */ #define ELEVATOR_ORIGIN_STOP_TIMER (500) typedef enum { MOW_ELEVATOR_GEAR_NONE, // 未知 MOW_ELEVATOR_GEAR_1, // 档位1 MOW_ELEVATOR_GEAR_2, // 档位2 MOW_ELEVATOR_GEAR_3, // 档位3 MOW_ELEVATOR_GEAR_4, // 档位4 MOW_ELEVATOR_GEAR_5, // 档位5 MOW_ELEVATOR_GEAR_6, // 档位6 MOW_ELEVATOR_GEAR_7, // 档位7 }mow_elevator_gear_e; typedef enum { MOW_ELEVATOR_STATUS_FINISH, // 档位完成状态 MOW_ELEVATOR_STATUS_GO_TO_ORIGIN, // 前往原点 MOW_ELEVATOR_STATUS_IN_ORIGIN, // 在原点 MOW_ELEVATOR_STATUS_RUNING, // 档位调节状态 MOW_ELEVATOR_STATUS_ERROR = 0xFF, // 故障 }mow_elevator_status_e; typedef enum { MOW_GRASS_STATUS_STOP, // 停止中 MOW_GRASS_STATUS_WORKING, // 工作中 }mow_grass_status_e; typedef struct { mow_elevator_status_e status; // 状态 mow_elevator_gear_e set_gear; // 设置档位 mow_elevator_gear_e now_gear; // 当前档位 float current; // 电流 单位A uint16_t press; // 触发计时 单位ms uint16_t release; // 释放计时 单位ms uint16_t adc_timer; // 堵转计时 uint16_t timer; // 计时 }mow_elevator_t; typedef struct { mow_grass_status_e status; // 状态 float target_speed; // 目标速度 单位m/s float now_speed; // 当前速度 单位m/s float current; // 电流 单位A bool brake; // 刹车 }mow_grass_t; /* * 函数名 :mow_init * 功能 :割草组件初始化 * 参数 :无 * 返回值 :无 * 备注 :无 */ void mow_init(void); /* * 函数名 :mow_elevator_gear_set * 功能 :设置升降电机档位 * 参数 :gear参考枚举体mow_elevator_gear_e * 返回值 :无 * 备注 :无 */ void mow_elevator_gear_set(mow_elevator_gear_e gear); /* * 函数名 :mow_grass_speed_set * 功能 :pid 设置割草电机速度 * 参数 :speed速度 单位m/s * 返回值 :无 * 备注 :无 */ void mow_grass_speed_set(float speed); /* * 函数名 :mow_elevator_get * 功能 :割草组件升降电机相关参数获取 * 参数 :无 * 返回值 :参考结构体mow_elevator_get * 备注 :无 */ mow_elevator_t mow_elevator_get(void); /* * 函数名 :mow_grass_get * 功能 :割草组件刀盘电机相关参数获取 * 参数 :无 * 返回值 :参考结构体mow_grass_t * 备注 :无 */ mow_grass_t mow_grass_get(void); /* * 函数名 :mow_timer_50ms_execute * 功能 :电机闭环定时器执行 * 参数 :无 * 返回值 :无 * 备注 :无 */ void mow_timer_50ms_execute(void); /* * 函数名 :mow_timer_1ms_execute * 功能 :割草组件计时 * 参数 :无 * 返回值 :无 * 备注 :无 */ void mow_timer_1ms_execute(void); #endif // MOW_SWITCH #endif /* MODULE_MODULE_MOW_MODULE_MOW_H_ */ 帮我注释以下
08-20
/* * module_mow.c * * Created on: Feb 19, 2025 * Author: XWM */ #include <module/module_mow/module_mow.h> #include <algorithm/pid/pid.h> #include <driver/driver_analog/driver_analog.h> #include <driver/driver_elevator_motor/driver_elevator_motor.h> #include <driver/driver_grass_motor/driver_grass_motor.h> #include <driver/driver_power/driver_power.h> #include <string.h> #include <stdlib.h> #if MOW_SWITCH /* 割草电机速度pid */ static pid_type mow_grass_pid; static mow_elevator_t mow_elevator; static mow_grass_t mow_grass; /* * 函数名 :mow_init * 功能 :割草组件初始化 * 参数 :无 * 返回值 :无 * 备注 :无 */ void mow_init(void) { memset(&mow_grass_pid, 0, sizeof(pid_type)); memset(&mow_elevator, 0, sizeof(mow_elevator_t)); memset(&mow_grass, 0, sizeof(mow_grass_t)); // mow_elevator.set_gear = MOW_ELEVATOR_GEAR_7; /* 刀盘电机硬件初始化 */ grass_motor_driver_init(); /* 刀盘电机PID初始化 */ pid_init(&mow_grass_pid); pid_param_set(&mow_grass_pid, 0.1, 0.2, 0.01); adc_init(); power_motor_enable(true); } /* * 函数名 :mow_elevator_gear_set * 功能 :设置升降电机档位 * 参数 :gear参考枚举体mow_elevator_gear_e * 返回值 :无 * 备注 :无 */ void mow_elevator_gear_set(mow_elevator_gear_e gear) { mow_elevator.set_gear = gear; /* 同档位重复设置,不运行 */ if(mow_elevator.now_gear == gear) { mow_elevator.status = MOW_ELEVATOR_STATUS_FINISH; } else { mow_elevator.status = MOW_ELEVATOR_STATUS_GO_TO_ORIGIN; } mow_elevator.set_gear = gear; mow_elevator.timer = 0; } /* * 函数名 :mow_grass_speed_set * 功能 :pid 设置割草电机速度 * 参数 :speed速度 单位m/s * 返回值 :无 * 备注 :无 */ void mow_grass_speed_set(float speed) { mow_grass.target_speed = speed; pid_target_set(&mow_grass_pid, speed); } /* * 函数名 :mow_elevator_get * 功能 :割草组件升降电机相关参数获取 * 参数 :无 * 返回值 :参考结构体mow_elevator_get * 备注 :无 */ mow_elevator_t mow_elevator_get(void) { return mow_elevator; } /* * 函数名 :mow_grass_get * 功能 :割草组件刀盘电机相关参数获取 * 参数 :无 * 返回值 :参考结构体mow_grass_t * 备注 :无 */ mow_grass_t mow_grass_get(void) { return mow_grass; } /* * 函数名 :mow_elevator * 功能 :割草升降 * 参数 :无 * 返回值 :无 * 备注 :无 */ static void mow_elevator_execute(void) { if(!ELEVATOR_HALL1_READ()) { if(mow_elevator.press > ELEVATOR_HALL_PRESS_RELEASE_TIMER) { mow_elevator.now_gear = MOW_ELEVATOR_GEAR_1; mow_elevator.press = 0; } mow_elevator.release = 0; } else if(mow_elevator.now_gear == MOW_ELEVATOR_GEAR_1) { if(mow_elevator.release > ELEVATOR_HALL_PRESS_RELEASE_TIMER) { mow_elevator.now_gear = MOW_ELEVATOR_GEAR_2; mow_elevator.release = 0; } mow_elevator.press = 0; } else if(!ELEVATOR_HALL2_READ()) { if(mow_elevator.press > ELEVATOR_HALL_PRESS_RELEASE_TIMER) { mow_elevator.now_gear = MOW_ELEVATOR_GEAR_3; mow_elevator.press = 0; } mow_elevator.release = 0; } else if(mow_elevator.now_gear == MOW_ELEVATOR_GEAR_3) { if(mow_elevator.release > ELEVATOR_HALL_PRESS_RELEASE_TIMER) { mow_elevator.now_gear = MOW_ELEVATOR_GEAR_4; mow_elevator.release = 0; } mow_elevator.press = 0; } else if(!ELEVATOR_HALL3_READ()) { if(mow_elevator.press > ELEVATOR_HALL_PRESS_RELEASE_TIMER) { mow_elevator.now_gear = MOW_ELEVATOR_GEAR_5; mow_elevator.press = 0; } mow_elevator.release = 0; } else if(mow_elevator.now_gear == MOW_ELEVATOR_GEAR_5) { if(mow_elevator.release > ELEVATOR_HALL_PRESS_RELEASE_TIMER) { mow_elevator.now_gear = MOW_ELEVATOR_GEAR_6; mow_elevator.release = 0; } mow_elevator.press = 0; } else if(!ELEVATOR_HALL4_READ()) { if(mow_elevator.press > ELEVATOR_HALL_PRESS_RELEASE_TIMER) { mow_elevator.now_gear = MOW_ELEVATOR_GEAR_7; mow_elevator.press = 0; } mow_elevator.release = 0; } else { if(mow_elevator.release > ELEVATOR_HALL_PRESS_RELEASE_TIMER) { mow_elevator.release = 0; } mow_elevator.press = 0; } uint16_t elevator_adc = analog_get().buffer[ADC_ELEVATOR_MOTOR]; mow_elevator.current = elevator_adc; if(elevator_adc < ELEVATOR_LOCKED_ROTOR_ADC) { mow_elevator.adc_timer = 0; } else { /* 堵转10秒 */ if(mow_elevator.adc_timer > ELEVATOR_LOCKED_ROTOR_TIMER) { mow_elevator.status = MOW_ELEVATOR_STATUS_ERROR; } } switch(mow_elevator.status) { case MOW_ELEVATOR_STATUS_GO_TO_ORIGIN: // 机器回到最原点过程 { /* 向下电机反转 */ elevator_motor_control(ELEVATOR_MOTOR_DESCEND); /* 检测是否到达最下点 */ if(mow_elevator.now_gear == MOW_ELEVATOR_GEAR_1) { elevator_motor_control(ELEVATOR_MOTOR_STOP); mow_elevator.status = MOW_ELEVATOR_STATUS_IN_ORIGIN; mow_elevator.timer = 0; } /* 超出时间,报错 */ else if(mow_elevator.timer > ELEVATOR_OVERTIME) { elevator_motor_control(ELEVATOR_MOTOR_STOP); mow_elevator.status = MOW_ELEVATOR_STATUS_ERROR; mow_elevator.timer = 0; } break; } case MOW_ELEVATOR_STATUS_IN_ORIGIN: // 到达原点停上0.5秒 { if(mow_elevator.timer > ELEVATOR_ORIGIN_STOP_TIMER) { mow_elevator.status = MOW_ELEVATOR_STATUS_RUNING; mow_elevator.timer = 0; } break; } case MOW_ELEVATOR_STATUS_RUNING: // 机器到达预定档位过程 { /* 电机开始上升 */ elevator_motor_control(ELEVATOR_MOTOR_RISE); /* 电机运动限定时间 */ if(mow_elevator.timer > ELEVATOR_OVERTIME) { mow_elevator.status = MOW_ELEVATOR_STATUS_ERROR; elevator_motor_control(ELEVATOR_MOTOR_STOP); mow_elevator.timer = 0; } /* 结束动作判断 */ else if(mow_elevator.set_gear == mow_elevator.now_gear) { mow_elevator.status = MOW_ELEVATOR_STATUS_FINISH; elevator_motor_control(ELEVATOR_MOTOR_STOP); mow_elevator.timer = 0; } break; } case MOW_ELEVATOR_STATUS_FINISH: // 达预定档位完毕 { elevator_motor_control(ELEVATOR_MOTOR_STOP); mow_elevator.timer = 0; break; } case MOW_ELEVATOR_STATUS_ERROR: // 故障 { elevator_motor_control(ELEVATOR_MOTOR_STOP); mow_elevator.timer = 0; break; } default: break; } } /* * 函数名 :mow_grass_execute * 功能 :割草刀盘 * 参数 :无 * 返回值 :无 * 备注 :无 */ static void mow_grass_execute(void) { /* 每毫秒获取编码器脉冲,转化为速度r/s */ float speed = (mow_motor_encode_get() * 20) / GRASS_CIRCLE_PULSE; if(GRASS_MOTOR_FR_READ() == GPIO_PIN_SET) { speed = -speed; } mow_motor_encode_set(0); mow_grass.now_speed = speed; mow_grass.status = speed != 0 ? MOW_GRASS_STATUS_WORKING : MOW_GRASS_STATUS_STOP; mow_grass.current = analog_get().buffer[ADC_GRASS_MOTOR]; int16_t pwm_grass = pid_realize(&mow_grass_pid, mow_grass.now_speed, GRASS_DEAD_ZONE, GRASS_INTEGRAL_ERR, GRASS_INTEGRAL_LIMIT); if(abs(pwm_grass) <= GRASS_MIN_PWM) { pwm_grass = 0; } mow_motor_pwm(pwm_grass); mow_grass.brake = GRASS_MOTOR_BRAKE_READ(); } /* * 函数名 :mow_timer_50ms_execute * 功能 :电机闭环定时器执行 * 参数 :无 * 返回值 :无 * 备注 :无 */ void mow_timer_50ms_execute(void) { adc_convert(); /* 割草升降 */ mow_elevator_execute(); /* 割草刀盘 */ mow_grass_execute(); } /* * 函数名 :mow_timer_1ms_execute * 功能 :割草组件计时 * 参数 :无 * 返回值 :无 * 备注 :无 */ void mow_timer_1ms_execute(void) { mow_elevator.press++; mow_elevator.release++; mow_elevator.adc_timer++; mow_elevator.timer++; } #endif 给上述添加注释
08-16
#include <reg52.h>// 引脚定义// 输出指示引脚sbit OUT_4F_DOWN = P1^0; // 脚3 - 4楼下外呼信号sbit OUT_3F_UP = P1^1; // 脚5 - 3楼上外呼信号sbit OUT_3F_DOWN = P1^2; // 脚7 - 3楼下外呼信号sbit OUT_2F_UP = P1^3; // 脚9 - 2楼上外呼信号sbit OUT_2F_DOWN = P1^4; // 脚11 - 2楼下外呼信号sbit OUT_1F_UP = P1^5; // 脚13 - 1楼上外呼信号// 输入控制引脚sbit IN_1F_UP_LED = P1^6; // 脚4 - -1楼上呼指示灯sbit IN_2F_DOWN_LED = P1^7; // 脚6 - 2楼下呼指示灯sbit IN_2F_UP_LED = P3^0; // 脚8 - 2楼上呼指示灯sbit IN_3F_DOWN_LED = P3^1; // 脚10 - 3楼下呼指示灯sbit IN_3F_UP_LED = P3^2; // 脚12 - 3楼上呼指示灯sbit IN_4F_DOWN_LED = P3^3; // 脚14 - 4楼下呼指示灯// 平层限位开关sbit LIMIT_4F = P3^4; // 脚15 - 4层平层限位开关sbit LIMIT_3F = P3^5; // 脚17 - 3层平层限位开关sbit LIMIT_2F = P3^6; // 脚19 - 2层平层限位开关sbit LIMIT_1F = P3^7; // 脚21 - 1层平层限位开关// 电梯控制sbit ELEVATOR_UP = P2^0; // 脚26 - 电梯上升控制sbit ELEVATOR_DOWN = P2^1; // 脚28 - 电梯下降控制// 楼层显示sbit FLOOR_A = P2^2; // 脚20 - 楼层显示-Asbit FLOOR_B = P2^3; // 脚22 - 楼层显示-Bsbit FLOOR_C = P2^4; // 脚24 - 楼层显示-C// 全局变量unsigned char current_floor = 1; // 当前楼层(1-4)bit elevator_moving = 0; // 电梯是否在移动bit direction_up = 1; // 移动方向(1:上行, 0:下行)// 延时函数void delay_ms(unsigned int ms) { unsigned int i, j; for(i = 0; i < ms; i++) for(j = 0; j < 123; j++);}// 更新楼层显示void update_floor_display(unsigned char floor) { switch(floor) { case 1: FLOOR_A = 0; FLOOR_B = 1; FLOOR_C = 1; break; case 2: FLOOR_A = 1; FLOOR_B = 0; FLOOR_C = 1; break; case 3: FLOOR_A = 0; FLOOR_B = 0; FLOOR_C = 1; break; case 4: FLOOR_A = 1; FLOOR_B = 1; FLOOR_C = 0; break; }}// 检测外呼按钮void check_external_buttons() { // 检测1楼上呼 if(OUT_1F_UP == 0) { // 假设低电平有效 IN_1F_UP_LED = 0; // 点亮指示灯 // 处理1楼上呼请求 if(current_floor > 1) { direction_up = 0; // 设置方向为下行 elevator_moving = 1; } } else { IN_1F_UP_LED = 1; // 关闭指示灯 } // 检测2楼上呼 if(OUT_2F_UP == 0) { IN_2F_UP_LED = 0; if(current_floor < 2) { direction_up = 1; elevator_moving = 1; } else if(current_floor > 2) { direction_up = 0; elevator_moving = 1; } } else { IN_2F_UP_LED = 1; } // 检测2楼下呼 if(OUT_2F_DOWN == 0) { IN_2F_DOWN_LED = 0; if(current_floor < 2) { direction_up = 1; elevator_moving = 1; } else if(current_floor > 2) { direction_up = 0; elevator_moving = 1; } } else { IN_2F_DOWN_LED = 1; } // 检测3楼上呼 if(OUT_3F_UP == 0) { IN_3F_UP_LED = 0; if(current_floor < 3) { direction_up = 1; elevator_moving = 1; } else if(current_floor > 3) { direction_up = 0; elevator_moving = 1; } } else { IN_3F_UP_LED = 1; } // 检测3楼下呼 if(OUT_3F_DOWN == 0) { IN_3F_DOWN_LED = 0; if(current_floor < 3) { direction_up = 1; elevator_moving = 1; } else if(current_floor > 3) { direction_up = 0; elevator_moving = 1; } } else { IN_3F_DOWN_LED = 1; } // 检测4楼下呼 if(OUT_4F_DOWN == 0) { IN_4F_DOWN_LED = 0; if(current_floor < 4) { direction_up = 1; elevator_moving = 1; } } else { IN_4F_DOWN_LED = 1; }}// 电梯移动控制void elevator_control() { if(elevator_moving) { if(direction_up) { ELEVATOR_UP = 0; // 启动上升 ELEVATOR_DOWN = 1; // 检查是否到达目标楼层 if(current_floor < 4) { // 模拟移动过程 delay_ms(1000); // 模拟楼层间移动时间 // 更新当前楼层 current_floor++; update_floor_display(current_floor); // 检查是否到达限位开关 switch(current_floor) { case 1: if(LIMIT_1F == 0) elevator_moving = 0; break; case 2: if(LIMIT_2F == 0) elevator_moving = 0; break; case 3: if(LIMIT_3F == 0) elevator_moving = 0; break; case 4: if(LIMIT_4F == 0) elevator_moving = 0; break; } } else { elevator_moving = 0; } } // 停止电梯 if(!elevator_moving) { ELEVATOR_UP = 1; ELEVATOR_DOWN = 1; } }}// 主函数void main() { // 初始化 P1 = 0xFF; P2 = 0xFF; P3 = 0xFF; // 初始楼层显示 update_floor_display(current_floor); while(1) { // 检测外呼按钮 check_external_buttons(); // 电梯移动控制 elevator_control(); // 简单延时 delay_ms(100); }} 解读以上代码实现的功能
06-20
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) + "秒)"); } } } }
06-23
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值