AnyLogic啤酒冷却流程Split Block实现及状态变量更新求助
解决AnyLogic啤酒冷却流程的订单分配与状态变量问题
一、状态变量LitersNewCooler/LitersOldCooler不更新的原因及修复
常见原因
- 未在冷却机资源的占用/释放事件中绑定变量更新逻辑:冷却机的容量变化未触发变量赋值
- 变量作用域错误:若变量定义在局部Agent(如Beer)中,流程块无法全局访问并修改
- 订单拆分后未同步更新:拆分出的子订单占用冷却机时,未将对应容量累加到状态变量
修复方法
绑定资源事件更新变量
假设用ResourcePool管理两台冷却机(newCooler和oldCooler),在ResourcePool的onSeize事件中添加代码:Beer currentOrder = (Beer)agent; if(resource == newCooler) { LitersNewCooler += currentOrder.Liters; } else { LitersOldCooler += currentOrder.Liters; }在
onRelease事件中添加代码:Beer currentOrder = (Beer)agent; if(resource == newCooler) { LitersNewCooler -= currentOrder.Liters; } else { LitersOldCooler -= currentOrder.Liters; }确认变量作用域
将LitersNewCooler和LitersOldCooler定义在**主环境(Main)**中,确保所有流程块(Split、SelectOutput、Seize等)都能直接访问和修改。拆分订单时同步更新
在Split块的「On split」动作中提前计算拆分容量,同步更新对应状态变量。
二、Split Block拆分逻辑修正
原Split块的函数未正确匹配冷却机容量,需重写自定义拆分逻辑:
- 在Split块的「Split into」选项中选择
custom,编写如下拆分函数:List<Beer> splitBeerOrder(Beer originalOrder) { List<Beer> splitBatches = new ArrayList<>(); int remainingLiters = originalOrder.Liters; // 先尝试用新冷却机剩余容量 int newCoolerFree = 1400 - LitersNewCooler; if(newCoolerFree > 0 && remainingLiters > 0) { int useNew = Math.min(remainingLiters, newCoolerFree); Beer newBatch = new Beer(this); newBatch.Liters = useNew; splitBatches.add(newBatch); remainingLiters -= useNew; } // 剩余容量用旧冷却机拆分 while(remainingLiters > 0) { int oldCoolerFree = 1000 - LitersOldCooler; int useOld = Math.min(remainingLiters, oldCoolerFree); Beer oldBatch = new Beer(this); oldBatch.Liters = useOld; splitBatches.add(oldBatch); remainingLiters -= useOld; } return splitBatches; } - 确保Split块设置为
Create new agents,生成独立的Beer子订单实例。
三、负载均衡逻辑实现
替换原「优先新机器」的硬编码逻辑,改为基于当前负载动态分配:
用SelectOutput块动态分流
在Split块之后添加SelectOutput块,两个分支分别对应新、旧冷却机,分支条件设置为:- 新冷却机分支:
(1400 - LitersNewCooler) >= (1000 - LitersOldCooler) - 旧冷却机分支:
(1400 - LitersNewCooler) < (1000 - LitersOldCooler)
优先分配剩余容量更大的冷却机,避免单台机器过载。
- 新冷却机分支:
自定义最优机器选择函数
如果用Seize块直接指定资源,可编写函数返回最优冷却机:Resource getBestCooler() { int newFree = 1400 - LitersNewCooler; int oldFree = 1000 - LitersOldCooler; if(newFree > 0 && (newFree >= oldFree || oldFree <= 0)) { return newCooler; } else if(oldFree > 0) { return oldCooler; } return null; // 无可用机器,进入等待队列 }在Seize块的「Resource」选项中选择
custom,调用getBestCooler()函数。
内容的提问来源于stack exchange,提问作者user25621023
相关产品推荐
相关产品推荐

