船舶运河入港模拟:双Source块特定到达场景下的延迟处理需求
船舶运河模拟中到达时间调整逻辑的实现方案
核心逻辑
检测第二个Source(ships_terc)生成的代理是否与第一个Source(ships_ac)已生成的代理在同一天到达,一旦匹配触发标记,后续所有ships_ac的代理到达时间自动加3小时。
分步实现
1. 添加全局状态变量
在模型的Main代理里定义两个变量:
boolean delayAcShips = false:标记是否需要延迟ships_ac的代理Date tercTriggerDate = null:记录触发延迟的ships_terc代理日期
2. 给ships_terc的Source块添加触发检测逻辑
打开ships_terc的Source块,在On exit动作中写入以下代码:
// 提取当前代理的日期部分(去掉时分秒) SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); String tercShipDate = dateFormatter.format(this.arrivalDate); // 检查已生成的ships_ac代理是否有同一天的 for (ShipAcAgent acShip : main.ships_ac.getAgents()) { String acShipDate = dateFormatter.format(acShip.arrivalDate); if (acShipDate.equals(tercShipDate)) { main.delayAcShips = true; break; } }
替换提示:ShipAcAgent是你ships_ac代理的实际类名,arrivalDate是代理中存储到达时间的字段名,根据你的模型调整。
3. 修改ships_ac的Source块到达时间计算方式
将ships_ac的Source块Arrival type改为Dynamic,然后在Arrival time表达式里写:
Date originalTime = this.originalArrivalData; if (main.delayAcShips) { // 加3小时(换算成毫秒:3*60*60*1000=10800000) return new Date(originalTime.getTime() + 10800000); } return originalTime;
替换提示:originalArrivalData是你在Agent Parameters中映射的原始到达时间字段,必须单独保留原始值,不能直接用修改后的时间。
4. 初始化状态(可选)
为了避免模拟残留状态影响下次运行,在模型启动时(比如Main代理的On startup动作)添加:
delayAcShips = false; tercTriggerDate = null;
注意要点
- 日期比较必须只取年月日部分,否则时分秒差异会导致判断错误
- 必须保留原始到达时间字段,不能直接修改数据库映射的时间,否则无法恢复原始值
- 如果ships_ac的代理生成顺序在ships_terc之后,要确保检测逻辑能覆盖到已生成的ships_ac代理
内容的提问来源于stack exchange,提问作者LeticiaMello
相关产品推荐
相关产品推荐

