客流策略计算结构调整

This commit is contained in:
walker-sheng 2021-01-28 09:09:46 +08:00
parent f6814f8e04
commit a1e2e9dc8c
12 changed files with 150 additions and 10 deletions

View File

@ -5,6 +5,7 @@ import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.StandPassenger;
import club.joylink.rtss.vo.client.passenger.PassengerFlowMessage2TD;
import lombok.Getter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -28,6 +29,8 @@ public class PassengerFlowSimulationData {
*/
private Map<String, StandPassenger> lpfStandMap = new ConcurrentHashMap<>();
private LocalDateTime nextRecommendTime;
public PassengerFlowSimulationData(String group,
PassengerFlowData passengerFlowData,
Map<String, StandPassengerFlow> standPassengerFlowMap,
@ -59,4 +62,8 @@ public class PassengerFlowSimulationData {
public boolean containsLpfStand(Stand stand) {
return this.lpfStandMap.containsKey(stand.getCode());
}
public void updateNextRecommendTime(LocalDateTime time) {
this.nextRecommendTime = time;
}
}

View File

@ -1,6 +1,8 @@
package club.joylink.rtss.simulation.cbtc.passenger.strategy;
public final class Config {
/** 策略计算推荐间隔,单位 - 分钟 */
public static final int CAL_INTERVAL = 5;
/** 策略向后推算的时间,单位 - 分钟 */
public static final int STRATEGY_CAL_TIME = 30;
/** 站台大客流判断基准值 */

View File

@ -141,6 +141,11 @@ public class JumpStrategyServiceImpl implements StrategyService<JumpStrategy> {
strategy.setCoTarget(strategy.getTarget1()*strategy.getW1()+strategy.getTarget2()*strategy.getW2());
}
@Override
public String getName() {
return "跳停策略服务";
}
private RealRun handleTrainLeave(StrategyCalculateData data, JumpStrategy strategy, TrainPassenger trainPassenger,
TripPlan tripPlan, StationPlan stationPlan, int offsetTime) {
Stand stand = strategy.getStand();

View File

@ -6,8 +6,12 @@ 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.ParkTimeStrategy;
import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.Strategy;
import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.StrategyCalculateData;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.SocketMessageVO;
import club.joylink.rtss.vo.client.WebSocketMessageType;
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
import club.joylink.rtss.websocket.StompMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -19,6 +23,7 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Slf4j
@Component
@ -33,15 +38,20 @@ public class LargePassengerFlowStrategyService {
private StompMessageService stompMessageService;
@Autowired
private ParkTimeStrategyServiceImpl parkTimeStrategyService;
private StrategyCalculateAndRecommendService strategyCalculateAndRecommendService;
@Scheduled(fixedRate = 30*1000)
@Scheduled(fixedRate = 10*1000)
public void checkLpf() {
List<PassengerFlowSimulationData> pfSimulationList = this.passengerFlowSimulateService.getPassengerFlowSimulations();
if (CollectionUtils.isEmpty(pfSimulationList)) {
return;
}
for (PassengerFlowSimulationData passengerFlowSimulationData : pfSimulationList) {
Simulation simulation = this.passengerFlowSimulateService.getSimulationByGroup(passengerFlowSimulationData.getGroup());
if (passengerFlowSimulationData.getNextRecommendTime() != null &&
simulation.getSystemTime().isBefore(passengerFlowSimulationData.getNextRecommendTime())) {
continue;
}
// 查询大客流站台
List<StandPassengerFlow> standPassengerFlowList = passengerFlowSimulationData.getAllStandPassengerFlow();
List<StandPassengerFlow> lpfList = new ArrayList<>();
@ -54,14 +64,22 @@ public class LargePassengerFlowStrategyService {
log.info(String.format("[%s]出现大客流,开始生成策略计算", lpfList.get(0).getStand().debugStr()));
// 发现大客流计算策略
StrategyCalculateData strategyCalculateData = this.buildStrategyCalculateData(passengerFlowSimulationData);
List<ParkTimeStrategy> parkTimeStrategies = this.parkTimeStrategyService.generateStrategy(strategyCalculateData);
for (ParkTimeStrategy parkTimeStrategy : parkTimeStrategies) {
this.parkTimeStrategyService.calculate(strategyCalculateData.clone(), parkTimeStrategy);
parkTimeStrategy.buildDescription();
parkTimeStrategy.handleTarget();
log.info(String.format("停站时间策略[%s]计算指标为:%s", parkTimeStrategy.getDescription(),
parkTimeStrategy.targetDebugStr()));
List<Strategy> recommendList = this.strategyCalculateAndRecommendService.calculateAndRecommend(strategyCalculateData);
if (!CollectionUtils.isEmpty(recommendList)) {
if (simulation == null) {
return;
}
Set<String> users = simulation.getSimulationUserIds();
String body = JsonUtils.writeValueAsString(recommendList);
SocketMessageVO<String> message = SocketMessageFactory
.build(WebSocketMessageType.LPF_STRATEGY_RECOMMEND, simulation.getGroup(), body);
this.stompMessageService.sendToUser(users, message);
}
// 设置下次推荐时间
passengerFlowSimulationData.updateNextRecommendTime(simulation.getSystemTime().plusMinutes(Config.CAL_INTERVAL));
} else {
// 没有大客流清除下次推荐时间
passengerFlowSimulationData.updateNextRecommendTime(null);
}
}
}

View File

@ -158,6 +158,11 @@ public class ParkTimeStrategyServiceImpl implements StrategyService<ParkTimeStra
}
}
@Override
public String getName() {
return "增加停站时间策略服务";
}
private RealRun handleTrainLeave(StrategyCalculateData data, ParkTimeStrategy strategy, TrainPassenger trainPassenger,
TripPlan tripPlan, StationPlan stationPlan, int offsetTime) {
Stand stand = strategy.getStand();

View File

@ -0,0 +1,62 @@
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
public class StrategyCalculateAndRecommendService implements ApplicationContextAware {
List<StrategyService> strategyServiceList = new ArrayList<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, StrategyService> strategyServiceMap = applicationContext.getBeansOfType(StrategyService.class);
strategyServiceMap.forEach((name, service) -> {
this.strategyServiceList.add(service);
});
}
public List<Strategy> calculateAndRecommend(StrategyCalculateData data) {
List<Strategy> strategyList = this.calculate(data);
return this.recommend(strategyList);
}
public List<Strategy> calculate(StrategyCalculateData data) {
List<Strategy> strategyList = new ArrayList<>();
for (StrategyService strategyService : this.strategyServiceList) {
StrategyCalculateData clone = data.clone();
List<Strategy> list = strategyService.generateStrategy(clone);
if (CollectionUtils.isEmpty(list)) {
log.info(String.format("大客流策略计算服务[%s]没有生成策略", strategyService.getName()));
continue;
}
for (Strategy strategy : list) {
strategyService.calculate(data.clone(), strategy);
strategy.handleTarget();
log.info(String.format("策略[%s]计算指标为:%s", strategy.getDescription(),
strategy.targetDebugStr()));
strategyList.add(strategy);
}
}
return strategyList;
}
public List<Strategy> recommend(List<Strategy> strategyList) {
List<Strategy> recommendList = new ArrayList<>();
if (!CollectionUtils.isEmpty(strategyList)) {
recommendList.addAll(strategyList);
}
return recommendList;
}
}

View File

@ -30,4 +30,6 @@ public interface StrategyService<T extends Strategy> {
.time(time.plusSeconds(offsetTime).atDate(systemTime.toLocalDate()))
.build();
}
String getName();
}

View File

@ -1,6 +1,7 @@
package club.joylink.rtss.simulation.cbtc.passenger.strategy.data;
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
@Getter
@ -8,12 +9,18 @@ public class JumpStrategy extends Strategy {
/**
* 站台
*/
@JsonIgnore
Stand stand;
public JumpStrategy(Stand stand) {
super(Type.JUMP);
this.stand = stand;
}
public String getStandCode() {
return this.stand.getCode();
}
@Override
public String buildDescription() {
this.description = String.format("站台%s设置跳停", stand.debugStr());

View File

@ -1,6 +1,7 @@
package club.joylink.rtss.simulation.cbtc.passenger.strategy.data;
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
@Getter
@ -8,13 +9,20 @@ public class ParkTimeStrategy extends Strategy {
/**
* 站台
*/
@JsonIgnore
Stand stand;
/** 停站时间 */
Integer time;
public ParkTimeStrategy(Stand stand, int parkTime) {
super(Type.PARK_TIME);
this.stand = stand;
this.time = parkTime;
this.buildDescription();
}
public String getStandCode() {
return this.stand.getCode();
}
@Override

View File

@ -32,6 +32,7 @@ public class StandPassenger {
public StandPassenger clone() {
StandPassenger obj = new StandPassenger();
obj.stand = this.stand;
obj.lpf = this.lpf;
obj.wait = this.wait;
return obj;
}

View File

@ -5,6 +5,23 @@ import lombok.Getter;
@Getter
public abstract class Strategy {
public enum Type {
/**
* 增加停站时间
*/
PARK_TIME,
/**
* 跳停
*/
JUMP,
/**
* 跳停+增加停站时间
*/
J_P,
}
Type type;
String description;
/** 指标1时刻表偏差 */
@ -22,6 +39,10 @@ public abstract class Strategy {
/** 综合指标对指标12加权求和 */
int coTarget;
public Strategy(Type type) {
this.type = type;
}
public abstract String buildDescription();
public void setTarget1(int target1) {

View File

@ -170,6 +170,8 @@ public enum WebSocketMessageType {
TRAIN_PIS,
/** 车站客流当前人数信息 */
STATION_PFI_NUM,
/** 大客流策略推荐消息 */
LPF_STRATEGY_RECOMMEND,
// ------------客流消息end------------
/** ------------维昂消息------------- */