You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AnyLogic随机分配服务逻辑异常:par_allowForGym为false时的循环问题

问题排查:随机分配服务的循环异常问题

代码功能说明

这段代码用于从wait队列释放首个元素,当服务存在剩余空间时,按随机规则将其分配至simulator或Gym服务。若生成的随机数无法匹配有效服务,最多重试生成100次随机数后退出循环。

代码实现

if (wait.size() > 1 && (simulators.size() < 6 || Gym.size() < 15)) {
    // Free the current wait and pick a service at random
    wait.free(wait.get(0));
    Random rand = new Random();
    int iterations = 0;

    while (true) {
        int randomNum = rand.nextInt(2) + 1; 
        if (randomNum == 1 && simulators.size() < 6) {
            // Choose the simulator service if there's space available
            wait.get(0).var_simulatorService = true;
            break;
        } else if (randomNum == 2 && Gym.size() < 15 && wait.get(0).par_allowForGym == true) {
            // Choose the gym service if there's space available
            wait.get(0).var_Gym = true;
            traceln("The agent number " + wait.get(0)+ " Alllow to go Gym - " + wait.get(0).par_allowForGym);
            break;
        } else {
            // generate a new random number if the previous one didn't lead to a valid service
            iterations++;
            if (iterations >= 100) {
                traceln("The agent number " + wait.get(0)+ " Alllow to go Gym - " + wait.get(0).par_allowForGym);
                break;
            }
        }
    }
}

问题描述

按照代码逻辑,当wait.get(0).par_allowForGym == false时,循环应持续生成随机数直到得到值1,否则最多执行100次后退出。但实际出现异常:循环未等到随机值为1就直接终止,需排查该问题原因。

相关截图

服务状态截图
日志输出截图

问题原因分析

  1. 外层判断与循环内状态不一致:外层的(simulators.size() < 6 || Gym.size() < 15)仅在进入代码块时执行一次。如果在循环过程中simulators服务被其他操作占满(size达到6),后续生成随机数1时,simulators.size() <6的条件不再满足,会直接进入else分支累加次数,直到100次后退出。
  2. 提前释放队列元素导致的异常:代码先执行wait.free(wait.get(0)),这会将队列首个元素从wait队列中移除,后续wait.get(0)可能指向队列的下一个元素,或者返回无效对象,导致par_allowForGym等属性的判断逻辑失效,循环提前终止。
  3. 无效重试的逻辑漏洞:当par_allowForGym == false且simulators服务已满时,生成的随机数无论是1还是2都无法匹配有效分支,此时循环会直接进入重试计数,直到100次后强制退出,这与预期的“持续等待随机值1”逻辑不符。

修复建议

  • 调整队列元素释放时机:将wait.free(wait.get(0))移至服务分配完成后的break之前,确保在整个分配逻辑中,wait.get(0)始终指向目标元素。
  • 优化循环内的服务可用性检查:在每次循环时重新确认可用服务,或者提前筛选出当前可用的服务列表,直接从可用列表中随机选择,避免无效的随机数生成。例如:
    // 提前获取可用服务选项
    List<Integer> availableServices = new ArrayList<>();
    if (simulators.size() <6) availableServices.add(1);
    if (Gym.size()<15 && wait.get(0).par_allowForGym) availableServices.add(2);
    // 从可用选项中随机选择
    if (!availableServices.isEmpty()) {
        int randomIndex = rand.nextInt(availableServices.size());
        int selected = availableServices.get(randomIndex);
        if (selected ==1) {
            wait.get(0).var_simulatorService = true;
        } else {
            wait.get(0).var_Gym = true;
            traceln("The agent number " + wait.get(0)+ " Alllow to go Gym - " + wait.get(0).par_allowForGym);
        }
        wait.free(wait.get(0));
    }
    
  • 强化外层进入条件:将外层判断改为wait.size()>1 && (simulators.size()<6 || (Gym.size()<15 && wait.get(0).par_allowForGym)),确保进入代码块时至少有一个服务可分配,避免进入循环后无有效选项的情况。

内容的提问来源于stack exchange,提问作者Aqeel Tariq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:15:42