R语言add_generator列车生成器未正常生成实体问题排查
问题描述
- 编写按指定时刻表生成乘客与列车的仿真代码时出现异常:
RegularPassenger(普通乘客)、SoldierPassenger(士兵乘客)均可按配置规则正常生成,但Train(列车)实体完全未被创建,常规排查手段未定位到问题。
涉及的列车调度函数代码:
TrainSchduale<- function(){ if (now(TrainSim)<9*60){ return(7*60) } else{ return (16*60) } }
涉及的生成器定义代码:
add_generator("Train", trainTraj, distribution = from_to( start_time= 1.5*60, stop_time= function ()TrainSchduale(), dist = function () 44.99, arrive = TRUE, every = NULL), mon=2) %>% add_generator("RegularPassenger",priority = 0, regularTraj, distribution = from_to(start_time=0, stop_time=16*60, dist=function () exp(0.6912117), arrive = TRUE, every = NULL), mon=2) %>% add_generator("SoldierPassenger",priority = 1, soldierTraj, distribution = from_to(start_time=0, stop_time=16*60, dist=function () exp(0.513304), arrive = TRUE, every = NULL), mon=2)
错误原因
代码存在3个核心问题,直接导致列车生成失败:
- 函数参数不匹配引发生成器初始化失败
simmer包中from_to的时间类参数如果传入函数,调用时会自动将当前仿真时间作为第一个参数传入。你定义的TrainSchduale没有设置入参,调用时会触发unused argument报错,直接导致列车生成器注册失败,这是列车完全不生成的核心原因。乘客生成器的stop_time直接传入数值常量,不会触发该问题,因此可以正常运行。 - 对
stop_time执行逻辑理解错误from_to的stop_time如果传入函数,仅会在生成器首次激活时调用1次,返回固定的停止时间,不会在仿真运行过程中动态更新。你写的分支判断逻辑,永远不会在仿真时间到达9点时再次触发,9点到16点的列车生成逻辑完全不会生效。 - 时间配置与时刻表逻辑冲突
你设置的列车生成start_time=1.5*60对应仿真时间1点30分,和常规首班列车7点的需求完全不符;同时调度函数中当仿真时间小于9点时返回的停止时间是7*60(7点),相当于7点就终止列车生成,本身逻辑矛盾。
修复方案
- 不需要动态调度函数的话,直接将列车生成的
stop_time固定为16*60,和乘客生成逻辑对齐,避免函数参数错误。 - 修正列车首班时间,如果首班为7点,将
start_time改为7*60。 - 固定间隔44.99分钟(接近45分钟每班)的配置可以保留,7点到16点共9小时,刚好可以覆盖全天班次。
修复后的生成器代码参考:
add_generator("Train", trainTraj, distribution = from_to( start_time= 7*60, # 首班7点 stop_time= 16*60, # 末班16点停止生成 dist = function () 44.99, arrive = TRUE, every = NULL), mon=2) %>% add_generator("RegularPassenger",priority = 0, regularTraj, distribution = from_to(start_time=0, stop_time=16*60, dist=function () exp(0.6912117), arrive = TRUE, every = NULL), mon=2) %>% add_generator("SoldierPassenger",priority = 1, soldierTraj, distribution = from_to(start_time=0, stop_time=16*60, dist=function () exp(0.513304), arrive = TRUE, every = NULL), mon=2)
如果确实需要动态调整停止时间,需要给调度函数增加入参接收当前仿真时间,同时配合every参数设置重新调度的周期,不能仅靠stop_time函数实现动态更新。
内容的提问来源于stack exchange,提问作者Gil Rodriguez
相关产品推荐
相关产品推荐

