AnyLogic建模求助:IBunits到达AtFirm状态时触发Firms状态转换
问题:AnyLogic供应链模型状态触发实现方案
我正在遵循供应链第三阶段模型模板构建AnyLogic模型,需求为:当IBunits代理到达AtFirm状态时,触发Firms角色从State1转换至State2。教程中的触发事件基于分布而非状态到达条件,无法直接复用原有代码。尝试创建OrderLink这类额外代理,但未解决问题,寻求可行实现方案。
相关资源
- IBunits状态图:

- Firm状态图:

- 原有基于分布的触发代码:
// create new Order object and fill its parameters OrderLink order = new OrderLink(uniform_discr(5, 20), this); // find available unit is in state "AtUni" IBunit iBunit = getNearestAgent( filter(main.iBunits, t -> t.inState(IBunit.AtUni))); // if you found a truck if (iBunit != null) { // assign this order to found truck iBunit.order = order; // tell the truck to trigger its statechart send(order, iBunit); }
可行实现方案
方案1:在IBunit状态图添加进入动作触发
- 打开IBunit代理的状态图,找到AtFirm状态,双击设置「进入动作(Entry action)」。
- 在动作中添加代码,定位对应Firm并触发状态转换:
// 这里假设IBunit有预先关联的Firm属性,比如this.assignedFirm;如果没有,需根据业务逻辑查找(比如按位置匹配) Firm targetFirm = this.assignedFirm; // 确认Firm存在且处于State1时触发转换 if(targetFirm != null && targetFirm.inState(Firm.State1)){ // 发送消息触发Firm的状态转换 send("triggerToState2", targetFirm); }
- 打开Firm代理的状态图,给State1到State2的转换添加消息触发器,消息名称设为
triggerToState2(需和上面send的消息名完全一致)。
方案2:全局事件监听状态变更
- 在主模型(Main)中创建一个周期性事件,间隔设为0.1秒(或更小,确保及时捕捉状态变更)。
- 在事件动作中添加过滤与触发逻辑:
// 筛选刚进入AtFirm状态的IBunit(通过状态进入时间匹配当前时间) List<IBunit> arrivedUnits = filter(main.iBunits, u -> u.inState(IBunit.AtFirm) && u.getStateEnterTime(IBunit.AtFirm) == time() ); for(IBunit unit : arrivedUnits){ // 按业务逻辑找到对应的Firm,示例:按距离最近匹配 Firm targetFirm = getNearestAgent(main.firms, unit); if(targetFirm != null && targetFirm.inState(Firm.State1)){ // 直接触发Firm状态图的转换事件(需提前在状态转换中定义内部事件) targetFirm.getStatechart().fireEvent("toState2"); } }
- 在Firm状态图的State1→State2转换中,添加内部事件触发器,事件名设为
toState2。
方案3:直接调用Firm状态转换方法
- 在IBunit代理中添加
Firm类型的属性(比如linkedFirm),在IBunit创建或分配流程中完成关联。 - 在IBunit的AtFirm状态进入动作中,直接调用Firm的状态转换:
if(linkedFirm != null && linkedFirm.inState(Firm.State1)){ // 直接跳转到State2,需确保状态图允许外部访问(状态图设置中开启「Allow external access」) linkedFirm.getStatechart().transitionTo(Firm.State2); }
内容的提问来源于stack exchange,提问作者LAPT
相关产品推荐
相关产品推荐

