电梯具体实现
前端
-
技术: vue 全家桶 + element
-
电梯页面
-
监控页面
-
配置页面
后端
-
技术: springboot + WebSocket + jdk + gradle +docker
-
分析
- 项目启动,前后端通过websocket建立通讯,后端定时把数据发送给前端,前端渲染页面com.emodernhy.elevator.service.impl.ElevatorService#showData
- 建立通讯后,所有电梯默认一层
- 电梯建立通讯后,会调用com.emodernhy.elevator.controller.WebSocketController#onOpen方法建立通讯
- 然后电梯会进行初始化com.emodernhy.elevator.service.impl.ElevatorService#app
- 这样电梯前期就建立完毕了.可以再页面点击按钮使用电梯
-
配置类
- 电梯初始化配置,这是在电梯系统启动前,就必须要有的参数,不然电梯无法运行
package com.emodernhy.elevator.config.yaml;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import java.io.Serializable;
/**
* 电梯相关配置 yaml配置转实体
*
* @author bo.huang
* @since 2020/4/21 9:19 下午
*/
@Configuration
@PropertySource(value = "classpath:application.yaml")
@ConfigurationProperties(prefix = "emodernhy.elevator.config")
@Data
public class ElevatorConfigYaml implements Serializable {
/**
* 电梯运行调度时间
*/
private Long runTime = 3000L;
/**
* 电梯等待调度时间
*/
private Long waitTime = 5000L;
/**
* 电梯派送调度时间
*/
private Long dispatchTime = 1000L;
/**
* 模式下滞留时间
*/
private Long strandedTime = 5000L;
/**
* 电梯个数
*/
private Integer elevatorCount = 3;
/**
* 楼层数
*/
private Integer floorCount = 19;
/**
* 限制人数
*/
private Integer peopleRestriction = 20;
}
- 电梯类
package com.emodernhy.elevator.mode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
/**
* 电梯类
*
* @author bo.huang
* @since 2020/4/29 2:58 下午
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel("电梯类")
public class Elevator implements Serializable {
@ApiModelProperty("电梯编号")
private Long elevatorId;
@ApiModelProperty("电梯名称")
private String elevatorName;
@ApiModelProperty("最大人数限制")
private Integer peopleRestriction;
@ApiModelProperty("电梯状态 1:闲置,2:运行,3:关门,4:开门,5:暂停,6:上行,7:下行")
private Integer status;
@ApiModelProperty("电梯即将运行状态 1:闲置,6:上行,7:下行")
private Integer state;
@ApiModelProperty("当前楼层")
private Integer currentFloor;
@ApiModelProperty("最大楼层")
private Integer maxFloor;
@ApiModelProperty("最小楼层")
private Integer minFloor;
@ApiModelProperty("当前人数")
private Integer currentPeople;
@ApiModelProperty("即将上电梯人数")
private Map<Integer, Integer> upPeople;
@ApiModelProperty("即将下电梯人数")
private Map<Integer, Integer> downPeople;
@ApiModelProperty("电梯按键")
private List<ElevatorButton> buttonList;
@ApiModelProperty("运行调度")
private ScheduledFuture<?> runFuture;
@ApiModelProperty("等待调度")
private ScheduledFuture<?> waitFuture;
@ApiModelProperty("是否到达任务楼层")
private Map<Integer, Boolean> taskFloorMap;
@ApiModelProperty("外部楼层按钮方向")
private Map<Integer, Integer> taskFloorDirection;
@ApiModelProperty("模式 1:节能模式 2:上行高峰 3:下行高峰 4:随机分配 5:指定楼层")
private Integer elevatorMode;
@ApiModelProperty("模式楼层")
private Integer moderFloor;
@ApiModelProperty("模式标记")
private Boolean moderFlag;
@ApiModelProperty("模式调度")
private ScheduledFuture<?> modeFuture;
}
- 楼层类
package com.emodernhy.elevator.mode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* 楼层
*
* @author bo.huang
* @since 2020/4/29 3:30 下午
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel("楼层显示")
public class Floor implements Serializable {
@ApiModelProperty("楼层数")
private Integer floorNo;
@ApiModelProperty("上行按键")
private ElevatorButton upButton;
@ApiModelProperty("下行按键")
private ElevatorButton downButton;
}
逻辑分析
- 当楼层外面按钮点击后,调用com.emodernhy.elevator.controller.ElevatorController#floorBut方法,
- 电梯会调用贪心算法com.emodernhy.elevator.service.impl.ElevatorService#schedule去计算电梯.
- 如果所有电梯都没有满足条件,会开启电梯派送调度器com.emodernhy.elevator.service.impl.ElevatorService#schedule电梯派送任务,直到找到电梯
- 找到电梯后,会给该电梯添加任务com.emodernhy.elevator.service.impl.ElevatorService#addJob
- 有了任务的电梯,会开启电梯运行任务调度器(也就是电梯上下运行的过程)com.emodernhy.elevator.service.impl.SchedulingService#run
- 运行任务调度器会计算出电梯的状态,如果没有到达楼层电梯继续进行运行任务直到到达楼层或者没有运行任务
- 电梯到达任务楼层后,会结束电梯运行任务调度器,进入等待,电梯等待任务调度器开启(也就是电梯开门,到关门).com.emodernhy.elevator.service.impl.SchedulingService#wait
- 电梯关门后,会结束等待任务调度器,继续开启电梯运行调度器,一直电梯空闲
- 模式任务调度器com.emodernhy.elevator.service.impl.SchedulingService#moder
- 就是当电梯空闲的时候,电梯会根据模式的不同,到达指定楼层.
- 节能模式:电梯空闲就不管不问
- 上行高峰模式: 电梯在空闲中是,5S(模式下滞留时间)后,电梯会自动去1层
- 下行高峰模式: 电梯在空闲中是,5S(模式下滞留时间)后,电梯会自动去顶层
- 指定楼层模式: 电梯在空闲中是,5S(模式下滞留时间)后,电梯会自动去指定层
- 随机模式: 电梯在空闲中是,5S(模式下滞留时间)后,电梯会自动去随机层
贪心算法选择电梯(猴子搬玉米,选择最好的)
- 电梯是暂停/关门,不选择
- 电梯反方向的跳过(我要上行,电梯下行),不选择
- 电梯反方向的跳过(我要下行,电梯上行),不选择
- 电梯方向下行,我要下行,电梯已经过楼层,不选择
- 电梯方向上行,我要上行,电梯已经过楼层,不选择
- 电梯超载跳过,不选择
- 相同电梯,选择距离最近的
- 相同距离,选择空闲的