diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java index 75c3c678b..a99990ba4 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java @@ -280,6 +280,7 @@ public class RouteService { public Route.CheckFailMessage setting(Simulation simulation, Route route) { Route.CheckFailMessage check = this.check(simulation, route); if (Objects.nonNull(check)) { + log.info(String.format("进路[%s]排列检查失败,无法排列:%s", route.debugStr(), check.debugStr())); return check; } // 进路开始办理 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java index f06ddddb9..54110005e 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java @@ -534,6 +534,10 @@ public class Route extends MapNamedElement { } return JsonUtils.writeValueAsString(map); } + + public String debugStr() { + return String.format("设备%s,失败原因:%s", this.device.debugStr(), this.reason); + } } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/PassengerFlowSimulateService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/PassengerFlowSimulateService.java index eb0b523f6..e4d5d523b 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/PassengerFlowSimulateService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/PassengerFlowSimulateService.java @@ -56,6 +56,9 @@ public class PassengerFlowSimulateService { @Autowired private MapPassengerFlowDataService mapPassengerFlowDataService; + public List getPassengerFlowSimulations() { + return new ArrayList<>(passengerFlowSimulationDataMap.values()); + } public boolean changePassengerFlow(String group, Long passengerFlowId) { if(!Objects.equals(group2mapPassengerFlowID.get(group),passengerFlowId)){ @@ -550,6 +553,10 @@ public class PassengerFlowSimulateService { return viewInfo.closeView(mapElement.getDeviceType()); } + public Simulation getSimulationByGroup(String group) { + return this.groupSimulationCache.getSimulationByGroup(group); + } + static class PassengerFlowViewInfo { String group; UserVO user; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/data/PassengerFlowSimulationData.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/data/PassengerFlowSimulationData.java index a4296cd05..135990607 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/data/PassengerFlowSimulationData.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/data/PassengerFlowSimulationData.java @@ -1,11 +1,14 @@ package club.joylink.rtss.simulation.cbtc.passenger.data; +import club.joylink.rtss.simulation.cbtc.data.map.Stand; +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.StandPassenger; import club.joylink.rtss.vo.client.passenger.PassengerFlowMessage2TD; import lombok.Getter; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; @Getter public class PassengerFlowSimulationData { @@ -20,6 +23,11 @@ public class PassengerFlowSimulationData { */ private List historyPassengerMessage2TD = new ArrayList<>(); + /** + * 出现大客流的站台 + */ + private Map lpfStandMap = new ConcurrentHashMap<>(); + public PassengerFlowSimulationData(String group, PassengerFlowData passengerFlowData, Map standPassengerFlowMap, @@ -37,4 +45,18 @@ public class PassengerFlowSimulationData { public List getAllTrainPassengerFlow() { return new ArrayList<>(trainPassengerFlowMap.values()); } + + public void addLpfStand(StandPassenger standPassenger) { + this.lpfStandMap.put(standPassenger.getStand().getCode(), standPassenger); + } + + public void setLpfStands(List lpfStandList) { + for (StandPassenger standPassenger : lpfStandList) { + this.lpfStandMap.put(standPassenger.getStand().getCode(), standPassenger); + } + } + + public boolean containsLpfStand(Stand stand) { + return this.lpfStandMap.containsKey(stand.getCode()); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/Config.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/Config.java new file mode 100644 index 000000000..ea78828a4 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/Config.java @@ -0,0 +1,16 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy; + +public final class Config { + /** 策略向后推算的时间,单位 - 分钟 */ + public static final int STRATEGY_CAL_TIME = 30; + /** 站台大客流判断基准值 */ + public static final int STAND_LPF_TRIGGER = 800; + /** 站台最大停站时间:单位 - 秒 */ + public static final int STAND_MAX_STOP_TIME = 90; + /** 列车最大容量 */ + public static final int TRAIN_CAPACITY = 1500; + /** 站台乘客上列车速度: 人/秒 (列车停站上车时间应该是总停站时间-(开关门6s+下车4s+发车前确认5s)) */ + public static final float PASSENGER_ON_SPEED = 12; + /** 列车跳停节省时间,单位 - 秒 */ + public static final int TRAIN_PASS_SAVE_TIME = 60; +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/LargePassengerFlowStrategyService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/LargePassengerFlowStrategyService.java new file mode 100644 index 000000000..54ff983d3 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/LargePassengerFlowStrategyService.java @@ -0,0 +1,65 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy; + +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; +import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; +import club.joylink.rtss.simulation.cbtc.passenger.PassengerFlowSimulateService; +import club.joylink.rtss.simulation.cbtc.passenger.data.PassengerFlowSimulationData; +import club.joylink.rtss.simulation.cbtc.passenger.data.StandPassengerFlow; +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.StrategyCalculateData; +import club.joylink.rtss.websocket.StompMessageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Component +public class LargePassengerFlowStrategyService { + + @Autowired + private PassengerFlowSimulateService passengerFlowSimulateService; + + @Autowired + private StompMessageService stompMessageService; + + @Scheduled(fixedRate = 300*1000) + public void checkLpf() { + List pfSimulationList = this.passengerFlowSimulateService.getPassengerFlowSimulations(); + if (CollectionUtils.isEmpty(pfSimulationList)) { + return; + } + for (PassengerFlowSimulationData passengerFlowSimulationData : pfSimulationList) { + // 查询大客流站台 + List standPassengerFlowList = passengerFlowSimulationData.getAllStandPassengerFlow(); + List lpfList = new ArrayList<>(); + for (StandPassengerFlow standPassengerFlow : standPassengerFlowList) { + if (standPassengerFlow.getPassengerQuantity() > Config.STAND_LPF_TRIGGER) { + lpfList.add(standPassengerFlow); + } + } + if (!lpfList.isEmpty()) { + // 发现大客流,计算策略 + StrategyCalculateData strategyCalculateData = this.buildStrategyCalculateData(passengerFlowSimulationData); + + } + } + } + + private StrategyCalculateData buildStrategyCalculateData(PassengerFlowSimulationData passengerFlowSimulationData) { + Simulation simulation = this.passengerFlowSimulateService.getSimulationByGroup(passengerFlowSimulationData.getGroup()); + SimulationDataRepository repository = simulation.getRepository(); + Map> serviceTripsMap = repository.getServiceTripsMap(); + StrategyCalculateData strategyCalculateData = new StrategyCalculateData( + serviceTripsMap, + repository.getRealRunRecordList(), + passengerFlowSimulationData.getAllStandPassengerFlow(), + passengerFlowSimulationData.getAllTrainPassengerFlow() + ); + return strategyCalculateData; + } + +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/ParkTimeStrategyServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/ParkTimeStrategyServiceImpl.java new file mode 100644 index 000000000..012e52ba2 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/ParkTimeStrategyServiceImpl.java @@ -0,0 +1,14 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy; + +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.Strategy; +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.StrategyCalculateData; +import org.springframework.stereotype.Component; + +@Component +public class ParkTimeStrategyServiceImpl implements StrategyService { + + @Override + public Strategy calculate(StrategyCalculateData data) { + return null; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/StrategyService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/StrategyService.java new file mode 100644 index 000000000..8f758f7b9 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/StrategyService.java @@ -0,0 +1,10 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy; + +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.Strategy; +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.StrategyCalculateData; + +public interface StrategyService { + + Strategy calculate(StrategyCalculateData data); + +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/ParkTimeStrategy.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/ParkTimeStrategy.java new file mode 100644 index 000000000..545b08cd2 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/ParkTimeStrategy.java @@ -0,0 +1,14 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy.data; + +public class ParkTimeStrategy extends Strategy { + /** 站台code */ + String standCode; + /** 停站时间 */ + Integer time; + + @Override + public String buildDescription() { + this.description = ""; + return null; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StandPassenger.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StandPassenger.java new file mode 100644 index 000000000..ae084a058 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StandPassenger.java @@ -0,0 +1,38 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy.data; + +import club.joylink.rtss.simulation.cbtc.data.map.Stand; +import club.joylink.rtss.simulation.cbtc.passenger.data.StandPassengerFlow; +import club.joylink.rtss.simulation.cbtc.passenger.strategy.Config; +import lombok.Getter; + +@Getter +public class StandPassenger { + + Stand stand; + + /** 是否大客流站 */ + boolean lpf; + /** + * 站台等待人数 + */ + int wait; + + private StandPassenger() { + + } + + public StandPassenger(StandPassengerFlow standPassengerFlow) { + this.stand = standPassengerFlow.getStand(); + this.wait = standPassengerFlow.getPassengerQuantity(); + if (this.wait > Config.STAND_LPF_TRIGGER) { + this.lpf = true; + } + } + + public StandPassenger clone() { + StandPassenger obj = new StandPassenger(); + obj.stand = this.stand; + obj.wait = this.wait; + return obj; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StationPassenger.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StationPassenger.java new file mode 100644 index 000000000..eb3577913 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StationPassenger.java @@ -0,0 +1,29 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy.data; + +import lombok.Getter; + +@Getter +public class StationPassenger { + + /** + * 车站code + */ + String code; + /** + * 车站等待人数 + */ + int wait; + + public StationPassenger(String code) { + this.code = code; + } + + public StationPassenger(String code, int wait) { + this.code = code; + this.wait = wait; + } + + public void addPassenger(int num) { + this.wait += num; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/Strategy.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/Strategy.java new file mode 100644 index 000000000..3918694f7 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/Strategy.java @@ -0,0 +1,15 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy.data; + +public abstract class Strategy { + + String description; + + /** 指标1:时刻表偏差 */ + Float target1; + /** 指标2:乘客等待时间 */ + Float target2; + /** 综合指标:对指标1,2加权求和 */ + Float coTarget; + + public abstract String buildDescription(); +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StrategyCalculateData.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StrategyCalculateData.java new file mode 100644 index 000000000..a6bc9189e --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StrategyCalculateData.java @@ -0,0 +1,79 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy.data; + +import club.joylink.rtss.simulation.cbtc.data.plan.RealRun; +import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; +import club.joylink.rtss.simulation.cbtc.passenger.data.StandPassengerFlow; +import club.joylink.rtss.simulation.cbtc.passenger.data.TrainPassengerFlow; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class StrategyCalculateData { + + /** + * key-服务号 + */ + Map> planMap; + /** + * key-服务车次号 + */ + Map> runMap; + + Map standPassengerMap; + + List trainPassengerList; + + private StrategyCalculateData() { + + } + + public StrategyCalculateData(Map> serviceTripsMap, + List realRunRecordList, + List allStandPassengerFlow, + List allTrainPassengerFlow) { + this.planMap = new HashMap<>(serviceTripsMap); + Map> realRunMap = new HashMap<>(); + for (RealRun realRun : realRunRecordList) { + String stNumber = realRun.getSTNumber(); + List list = realRunMap.get(stNumber); + if (list == null) { + list = new ArrayList<>(); + realRunMap.put(stNumber, list); + } + list.add(realRun); + } + this.runMap = realRunMap; + Map spMap = new HashMap<>(); + for (StandPassengerFlow standPassengerFlow : allStandPassengerFlow) { + StandPassenger standPassenger = new StandPassenger(standPassengerFlow); + spMap.put(standPassenger.getStand().getCode(), standPassenger); + } + this.standPassengerMap = spMap; + List tpList = new ArrayList<>(); + for (TrainPassengerFlow trainPassengerFlow : allTrainPassengerFlow) { + TrainPassenger trainPassenger = new TrainPassenger(trainPassengerFlow); + tpList.add(trainPassenger); + } + this.trainPassengerList = tpList; + } + + public StrategyCalculateData clone() { + StrategyCalculateData obj = new StrategyCalculateData(); + obj.planMap = new HashMap<>(this.planMap); + obj.runMap = new HashMap<>(this.runMap); + Map standPassengerMap = new HashMap<>(); + this.standPassengerMap.forEach((code, standPassenger) -> { + standPassengerMap.put(code, standPassenger.clone()); + }); + obj.standPassengerMap = standPassengerMap; + List tpList = new ArrayList<>(); + for (TrainPassenger trainPassenger : this.trainPassengerList) { + tpList.add(trainPassenger.clone()); + } + obj.trainPassengerList = tpList; + return obj; + } + +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/TrainPassenger.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/TrainPassenger.java new file mode 100644 index 000000000..24bb51080 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/TrainPassenger.java @@ -0,0 +1,36 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy.data; + +import club.joylink.rtss.simulation.cbtc.passenger.data.TrainPassengerFlow; +import lombok.Getter; + +@Getter +public class TrainPassenger { + + private String groupNumber; + /** 服务号 */ + String serviceNumber; + /** 车次号 */ + String tripNumber; + + /** 列车上人数 */ + int remain; + + public TrainPassenger() { + } + + public TrainPassenger(TrainPassengerFlow tpf) { + this.groupNumber = tpf.getTrain().getGroupNumber(); + this.serviceNumber = tpf.getTrain().getServiceNumber(); + this.tripNumber = tpf.getTrain().getTripNumber(); + this.remain = tpf.getPassengerQuantity(); + } + + public TrainPassenger clone() { + TrainPassenger obj = new TrainPassenger(); + obj.groupNumber = this.groupNumber; + obj.serviceNumber = this.serviceNumber; + obj.tripNumber = this.tripNumber; + obj.remain = this.remain; + return obj; + } +}