From f6814f8e0445d9e3fdaa2fb53876e9f4735fb8dc Mon Sep 17 00:00:00 2001 From: walker-sheng Date: Wed, 27 Jan 2021 15:33:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=A2=E6=B5=81=E6=A8=A1=E6=8B=9F=E4=BB=BF?= =?UTF-8?q?=E7=9C=9F=E9=80=BB=E8=BE=91=E8=B0=83=E6=95=B4=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=81=9C=E7=AB=99=E6=97=B6=E9=97=B4=E7=AD=96=E7=95=A5?= =?UTF-8?q?=E9=80=BB=E8=BE=91bug=20=E6=B7=BB=E5=8A=A0=E8=B7=B3=E5=81=9C?= =?UTF-8?q?=E7=AD=96=E7=95=A5=E5=92=8C=E8=AE=A1=E7=AE=97=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=EF=BC=8C=E6=9C=AA=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cbtc/ATS/service/AtsPlanService.java | 7 +- .../PassengerFlowSimulateService.java | 5 +- .../passenger/data/TrainPassengerFlow.java | 6 +- .../strategy/JumpStrategyServiceImpl.java | 158 ++++++++++++++++++ .../LargePassengerFlowStrategyService.java | 1 + .../strategy/ParkTimeStrategyServiceImpl.java | 31 ++-- .../passenger/strategy/data/JumpStrategy.java | 22 +++ .../passenger/strategy/data/Strategy.java | 6 +- .../strategy/data/StrategyCalculateData.java | 21 +++ 9 files changed, 237 insertions(+), 20 deletions(-) create mode 100644 src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/JumpStrategyServiceImpl.java create mode 100644 src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/JumpStrategy.java diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsPlanService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsPlanService.java index 3eaaa928d..592fba715 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsPlanService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsPlanService.java @@ -157,6 +157,10 @@ public class AtsPlanService { hold = this.atsStandService.isHoldTrain(target); } // 更新跳停状态 + if (jump && Objects.equals(tripPlan.getLastStationPlan().getStation(), target.getStation())) { + // 最后一站,不跳停 + jump = false; + } if (!Objects.equals(train.isJump(), jump)) { if (jump) { this.onboardAtpApiService.setJump(simulation, train.getGroupNumber()); @@ -365,7 +369,8 @@ public class AtsPlanService { } LocalTime arriveTime = systemTime.plusSeconds(intervalRunTime); train.updateEstimatedArriveInfo(nextStationPlan.getSection(), arriveTime); - if (this.atsStandService.isJump(nextStationPlan.getSection(), train.getGroupNumber())) { + if (!tripPlan.isLastPlan(nextStationPlan) && + this.atsStandService.isJump(nextStationPlan.getSection(), train.getGroupNumber())) { this.onboardAtpApiService.setJump(simulation, train.getGroupNumber()); } } else { 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 ef8a4647f..c34633a1a 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 @@ -296,7 +296,6 @@ public class PassengerFlowSimulateService { StandTimePassengerFlowData flowData = standTimePassengerFlowDataMap.get(stand.getCode()); StandTimePassengerFlowData preData = preTimePassengerFlowDataMap.get(stand.getCode()); int add = flowData.getNum() - preData.getNum(); - log.debug(String.format("站台[%s]增加乘客: %s", stand.debugStr(), add)); if (add < 0) { // 列车拉走了站台上的人 if (flowData.getNum() != 0 && preData.getNum() > 1000) { @@ -305,6 +304,7 @@ public class PassengerFlowSimulateService { add = flowData.getNum(); } } + log.debug(String.format("站台[%s]增加乘客: %s", stand.debugStr(), add)); int total = standPassengerFlow.plus(add); sendData.put("standCode", stand.getCode()); sendData.put("num", total); @@ -392,7 +392,7 @@ public class PassengerFlowSimulateService { // 如果没有数据,默认下车5%的人 down = (int) (trainPassengerFlow.getPassengerQuantity() * 0.05); } - trainPassengerFlow.minus(down); + down = trainPassengerFlow.minus(down); } sendData.put("out", down); // 上车 @@ -406,6 +406,7 @@ public class PassengerFlowSimulateService { } trainPassengerFlow.plus(up); sendData.put("in", up); + sendData.put("remain", trainPassengerFlow.getPassengerQuantity()); String json = JsonUtils.writeValueNullableFieldAsString(sendData); SocketMessageVO message = SocketMessageFactory.build( diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/data/TrainPassengerFlow.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/data/TrainPassengerFlow.java index fdd4cdd48..88bf2846a 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/data/TrainPassengerFlow.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/data/TrainPassengerFlow.java @@ -24,13 +24,15 @@ public class TrainPassengerFlow { this.off = false; } - public void minus(int num) { + public int minus(int num) { + this.off = true; if (this.passengerQuantity < num) { + num = this.passengerQuantity; this.passengerQuantity = 0; } else { this.passengerQuantity -= num; } - this.off = true; + return num; } public void plus(int up) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/JumpStrategyServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/JumpStrategyServiceImpl.java new file mode 100644 index 000000000..45a9b516b --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/JumpStrategyServiceImpl.java @@ -0,0 +1,158 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy; + +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.cbtc.data.map.Stand; +import club.joylink.rtss.simulation.cbtc.data.plan.RealRun; +import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan; +import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.JumpStrategy; +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.StandPassenger; +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.StrategyCalculateData; +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.TrainPassenger; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.time.LocalTime; +import java.util.*; + +@Slf4j +@Component +public class JumpStrategyServiceImpl implements StrategyService { + + @Override + public List generateStrategy(StrategyCalculateData data) { + List list = new ArrayList<>(); + Stand stand = null; + // 暂时按一个站大客流处理 + List standPassengerList = data.getAllStandPassengerList(); + for (StandPassenger standPassenger : standPassengerList) { + if (standPassenger.isLpf()) { + stand = standPassenger.getStand(); + break; + } + } + if (stand == null) { + return null; + } + List leftStandList = data.getLeftStandList(); + List rightStandList = data.getRightStandList(); + boolean right = false; + int index = leftStandList.indexOf(stand); + if (index < 0) { + // 不是左向站台 + right = true; + index = rightStandList.indexOf(stand); + } + BusinessExceptionAssertEnum.DATA_ERROR.assertTrue(index >= 0, String.format("未找到站台[%s]", stand.debugStr())); + + log.debug(String.format("生成跳停策略[%s]个", list.size())); + return list; + } + + @Override + public void calculate(StrategyCalculateData data, JumpStrategy strategy) { + // 系统时间 + LocalTime systemTime = data.getSystemTime().toLocalTime();// 系统当前时间 + LocalTime endTime = systemTime.plusMinutes(Config.STRATEGY_CAL_TIME);// 预测计算终点 + List trainPassengerList = data.getTrainPassengerList(); + Map trainPreviousMap = new HashMap<>(); // 列车上一个到站/发车数据 + int i = 0; + while (systemTime.isBefore(endTime) && i<1000) { // 在计算时间内 + ++i; + if (i > 999) { + log.error("死循环--------------------------"); + } + LocalTime nextTime = null; + for (TrainPassenger trainPassenger : trainPassengerList) { + String groupNumber = trainPassenger.getGroupNumber(); + TripPlan tripPlan = data.queryTripPlan(trainPassenger.getServiceNumber(), trainPassenger.getTripNumber()); + if (tripPlan == null) { // 未找到计划,跳过 + log.warn(String.format("列车[%s-%s|%s]没有找到车次计划", + groupNumber, trainPassenger.getServiceNumber(), trainPassenger.getTripNumber())); + continue; + } + if (tripPlan.isBackup()) { + continue; + } + // 上一实际到发 + RealRun realRun = trainPreviousMap.get(groupNumber); + if (realRun == null) { + realRun = data.queryPreviousRealRunData(groupNumber); + if (realRun != null) { + trainPreviousMap.put(groupNumber, realRun); + } + } + List planList = tripPlan.getPlanList(); + int offsetTime = 0; + StationPlan nextStationPlan = null; + if (realRun != null && + Objects.equals(tripPlan.getServiceNumber(), realRun.getServiceNumber()) && + Objects.equals(tripPlan.getTripNumber(), realRun.getTripNumber())) { + // 上一实际运行数据存在且在当前计划中 + // 查询实际运行到的车站计划 + StationPlan stationPlan = tripPlan.queryStationPlanByStationCode(realRun.getStationCode()); + BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(stationPlan); + LocalTime leaveTime = stationPlan.getLeaveTime(); + if (realRun.isArrive()) { + // 是到达车站的计划,预测离站 + LocalTime arriveTime = stationPlan.getArriveTime(); + if (!tripPlan.isFirstPlan(stationPlan)) { + offsetTime = realRun.getTime().toLocalTime().toSecondOfDay() - arriveTime.toSecondOfDay(); + } + RealRun leave = this.handleTrainLeave(data, strategy, trainPassenger, tripPlan, stationPlan, offsetTime); + + trainPreviousMap.put(groupNumber, leave); + } else { + offsetTime = realRun.getTime().toLocalTime().toSecondOfDay() - leaveTime.toSecondOfDay(); + } + if (tripPlan.isLastPlan(stationPlan)) { + // 最后一个到发计划,获取下一个折返后车次计划 + TripPlan nextTripPlan = data.queryNextTripPlan(tripPlan); + if (nextTripPlan != null) { + tripPlan = nextTripPlan; + nextStationPlan = nextTripPlan.getFirstStationPlan(); + } + } else { + nextStationPlan = tripPlan.queryNextStationPlanByStationCode(realRun.getStationCode()); + } + } else { + for (StationPlan stationPlan : planList) { + if (stationPlan.getArriveTime().compareTo(systemTime) >= 0) { + nextStationPlan = stationPlan; + break; + } + } + } + if (nextStationPlan != null) { + LocalTime arriveTime = nextStationPlan.getArriveTime(); + RealRun arrive = this.buildRealRun(groupNumber, tripPlan, nextStationPlan, true, arriveTime, offsetTime, data.getSystemTime()); + data.addRealRun(arrive); + RealRun leave = this.handleTrainLeave(data, strategy, trainPassenger, tripPlan, nextStationPlan, offsetTime); + data.addRealRun(leave); + trainPreviousMap.put(groupNumber, leave); + if (nextTime == null || leave.getTime().toLocalTime().isBefore(nextTime)) { + nextTime = leave.getTime().toLocalTime(); + } + } + } + BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(nextTime); + systemTime = nextTime; + } + strategy.setCoTarget(strategy.getTarget1()*strategy.getW1()+strategy.getTarget2()*strategy.getW2()); + } + + private RealRun handleTrainLeave(StrategyCalculateData data, JumpStrategy strategy, TrainPassenger trainPassenger, + TripPlan tripPlan, StationPlan stationPlan, int offsetTime) { + Stand stand = strategy.getStand(); + LocalTime arriveTime = stationPlan.getArriveTime(); + LocalTime leaveTime = stationPlan.getLeaveTime(); + // 生成预测实际运行图 + RealRun leave = this.buildRealRun(trainPassenger.getGroupNumber(), tripPlan, stationPlan, false, leaveTime, offsetTime, data.getSystemTime()); + data.addRealRun(leave); + // 大客流站计算指标 + if (Objects.equals(stationPlan.getSection(), stand.getSection())) { + + } + return leave; + } +} 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 index c1b3e6830..80d6d165a 100644 --- 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 @@ -58,6 +58,7 @@ public class LargePassengerFlowStrategyService { for (ParkTimeStrategy parkTimeStrategy : parkTimeStrategies) { this.parkTimeStrategyService.calculate(strategyCalculateData.clone(), parkTimeStrategy); parkTimeStrategy.buildDescription(); + parkTimeStrategy.handleTarget(); log.info(String.format("停站时间策略[%s]计算指标为:%s", parkTimeStrategy.getDescription(), parkTimeStrategy.targetDebugStr())); } 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 index e83f3ed17..cf27c6496 100644 --- 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 @@ -79,15 +79,6 @@ public class ParkTimeStrategyServiceImpl implements StrategyService planList = tripPlan.getPlanList(); int offsetTime = 0; StationPlan nextStationPlan = null; @@ -114,7 +119,6 @@ public class ParkTimeStrategyServiceImpl implements StrategyService standPassengerMap = new ConcurrentHashMap<>(); + List leftStandList; + + List rightStandList; + List trainPassengerList; private StrategyCalculateData() { @@ -56,6 +60,21 @@ public class StrategyCalculateData { StandPassenger standPassenger = new StandPassenger(standPassengerFlow); this.standPassengerMap.put(standPassenger.getStand().getCode(), standPassenger); } + List leftList = new ArrayList<>(); + List rightList = new ArrayList<>(); + for (StandPassengerFlow standPassengerFlow : allStandPassengerFlow) { + Stand stand = standPassengerFlow.getStand(); + if (stand.isRight()) { + rightList.add(stand); + } else { + leftList.add(stand); + } + } + leftList.sort(Comparator.comparing((stand) -> stand.getStation().getSn())); + rightList.sort(Comparator.comparing((stand) -> stand.getStation().getSn())); + Collections.reverse(leftList); + this.leftStandList = leftList; + this.rightStandList = rightList; List tpList = new ArrayList<>(); for (TrainPassengerFlow trainPassengerFlow : allTrainPassengerFlow) { if (!StringUtils.hasText(trainPassengerFlow.getTrain().getServiceNumber())) { @@ -85,6 +104,8 @@ public class StrategyCalculateData { standPassengerMap.put(code, standPassenger.clone()); }); obj.standPassengerMap = standPassengerMap; + obj.leftStandList = this.leftStandList; + obj.rightStandList = this.rightStandList; List tpList = new ArrayList<>(); for (TrainPassenger trainPassenger : this.trainPassengerList) { tpList.add(trainPassenger.clone());