如何让AnyLogic的delay函数每次触发时重启延迟计时?
AnyLogic系统动力学中实现条件触发时重置延迟的方案
你当前使用的delay()函数是AnyLogic的固定延迟函数,它的计时起点是仿真启动时刻,无法在条件每次满足时重置计时,因此需要改用状态变量+离散事件触发的方式实现需求,具体步骤如下:
1. 定义辅助变量
在模型中添加以下全局变量(类型按标注设置):
boolean conditionMet:记录当前触发条件是否满足double targetValue:存储条件满足时要输出的目标数值(0.3/0.6/0.8/1)double delayDuration:存储对应条件的延迟时长(10/4/3/2)boolean delayActive:标记是否正在执行延迟流程double finalOutput:最终输出结果(替代原代码中的delay()函数)
2. 编写条件监测与延迟控制逻辑
在所有影响触发条件的变量(complexity、stressresponse、boredom、wellbeing)的onChange事件中添加以下代码(注意统一变量名,原代码中英文/德文变量混用,需全部修正为一致命名):
// 计算当前条件、目标值及延迟时长 double tempValue = 0; double tempDelay = 0; boolean tempCondition = false; if (complexity <= 2) { tempCondition = (stressresponse + boredom) <= 2 && wellbeing >= 0.8; tempValue = 0.3; tempDelay = 10; } else if (complexity > 2 && complexity <= 5) { tempCondition = (stressresponse + boredom) <= 2 && wellbeing >= 0.8; tempValue = 0.6; tempDelay = 4; } else if (complexity > 5 && complexity <= 8) { tempCondition = (stressresponse + boredom) <= 2 && wellbeing >= 0.8; tempValue = 0.8; tempDelay = 3; } else if (complexity > 8 && complexity <= 10) { tempCondition = (stressresponse + boredom) <= 2 && wellbeing >= 0.8; tempValue = 1; tempDelay = 2; } // 处理条件变化逻辑 if (tempCondition) { // 条件满足时,若未在延迟中或参数变化,则重置延迟 if (!delayActive || targetValue != tempValue || delayDuration != tempDelay) { targetValue = tempValue; delayDuration = tempDelay; // 取消之前未完成的延迟事件 cancelDelayedAction("resetDelay"); // 启动新延迟,到期后设置输出值 delay(delayDuration, () -> { finalOutput = targetValue; delayActive = false; }, "resetDelay"); delayActive = true; // 延迟期间输出保持0 finalOutput = 0; } } else { // 条件不满足时,取消延迟并重置输出 cancelDelayedAction("resetDelay"); delayActive = false; finalOutput = 0; }
3. 替换原代码引用
将原代码中的整个三元表达式替换为finalOutput变量,让模型使用这个经过延迟控制的输出值。
注意事项
- 必须统一变量命名:原代码中同时存在英文(如
stressresponse)和德文(如Stressreaktion)变量,需全部修正为同一命名,否则逻辑会失效。 - 确保所有影响触发条件的变量都添加了
onChange事件,保证条件变化能被及时监测到。 cancelDelayedAction用于取消之前未完成的延迟,确保每次条件满足时都从触发时刻重新开始计时。
内容的提问来源于stack exchange,提问作者Nico
相关产品推荐
相关产品推荐

