AnyLogic随机数分配服务逻辑异常问题排查
问题排查与修复方案
核心问题
代码里先执行了 wait.free(wait.get(0)),这一步应该是把待处理的元素从wait集合中移除了,但后续循环里依然用 wait.get(0) 操作,这时候拿到的已经不是原本要处理的那个元素——原来的元素已经被移出wait集合,现在的wait.get(0)是队列里的下一个元素。
当原本的元素par_allowForGym == false时,我们需要把它分配到simulator,但因为代码错误地操作了新的队列首元素,导致逻辑完全混乱:要么新元素不符合条件,要么循环一直在错误的对象上判断,最终跑满100次才退出。
修复步骤
- 先把要处理的元素存到临时变量里,避免后续集合变化导致对象丢失
- 再执行free操作,最后用临时变量完成分配逻辑
修复后的代码:
if (wait.size() > 1 && (simulators.size() < 6 || Gym.size() < 15)) { // 先把要处理的元素存到临时变量 var agent = wait.get(0); // 释放该元素 wait.free(agent); Random rand = new Random(); int iterations = 0; while (true) { int randomNum = rand.nextInt(2) + 1; if (randomNum == 1 && simulators.size() < 6) { agent.var_simulatorService = true; break; } else if (randomNum == 2 && Gym.size() < 15 && agent.par_allowForGym == true) { agent.var_Gym = true; traceln("The agent number " + agent + " Alllow to go Gym - " + agent.par_allowForGym); break; } else { iterations++; if (iterations >= 100) { traceln("The agent number " + agent + " Alllow to go Gym - " + agent.par_allowForGym); break; } } } }
额外优化建议
- 可以提前判断当前agent的可选服务,避免无效的随机重试:比如如果agent不能去Gym,直接分配到simulator(如果有位置),不用进入循环随机
- 把Random实例提到循环外,避免每次创建新的Random对象,提升效率
内容的提问来源于stack exchange,提问作者Aqeel Tariq
相关产品推荐
相关产品推荐

