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

OPL CPLEX数组索引越界问题求助(含循环固定变量代码)

OPL CPLEX数组索引越界问题求助(含循环固定变量代码)

嗨,我来帮你拆解下这个索引越界的问题,结合你的错误提示和代码细节来看,问题主要出在数组初始化和集合传递的逻辑上,咱们一步步分析:

首先定位错误根源

你遇到的 "Index out of bound for array "x(8)": 2." 错误,本质是代码中访问了数组/变量未定义的索引范围。结合你的代码,核心问题有两个:

  1. output数组初始化长度严重不足
    你一开始定义var output = new Array(3);,后续又给output[i][j]赋值时用到了i=1~5、j=1~7,甚至后面要存储r=6~12的结果——但Array(3)生成的数组只有0/1/2三个索引位,访问j=3及以上、i=3及以上都会直接越界。

  2. N集合的传递逻辑有问题
    你每次迭代时用data.N=thisOplModel.s;,但thisOplModel.s初始是空集合,后续只添加当前iter,导致每次N集合只有单个元素;同时output无法匹配N中动态增加的索引值,进一步加剧了越界问题。

针对性修改方案

我把你的代码调整了关键部分,解决越界问题的同时优化了固定变量的逻辑:

main{
    var source = new IloOplModelSource("subset.mod");
    var cplex = new IloCplex();
    var def = new IloOplModelDefinition(source);
    
    // 改用键值对对象存储output,彻底避免数组索引越界
    var output = {};
    for (var k=1; k<=5; k++) {
        output[k] = {};
        for(var r=1; r<=12; r++) {
            output[k][r] = 0.0;
        }
    }
    
    // 维护累积的N集合,确保每次迭代的变量维度正确
    var currentN = new IloIntSet();
    var isFirstIter = true;
    
    for(var iter=6;iter<=12;iter++) {
        currentN.add(iter);
        cplex.tilim=300;
        var opl = new IloOplModel(def,cplex);
        var data= new IloOplDataElements();
        
        data.N = currentN;
        data.M = thisOplModel.M;
        data.Links = thisOplModel.Links;
        
        opl.addDataSource(data);
        opl.generate();
        
        // 第一次迭代没有上一步解,跳过固定变量逻辑
        if (!isFirstIter){
            for (var r in currentN){
                for (var k in data.M){
                    if (output[k][r] === 1){
                        opl.x[k][r].LB = output[k][r];
                        opl.x[k][r].UB = output[k][r];
                        writeln("xds[",k,"][",r,"] = ",output[k][r]);
                    }
                }
            }
        }
        
        // 增加求解判断,避免无解时访问solutionValue报错
        if (cplex.solve()) {
            opl.postProcess();
            for (var k in data.M){
                for (var r in currentN){
                    output[k][r] = opl.x[k][r].solutionValue;
                }
            }
        } else {
            writeln("迭代", iter, "求解失败");
        }
        
        data.end();
        opl.end();
        isFirstIter = false;
    }
}

额外注意事项

  • 请确保你的subset.mod中x变量的定义是dvar boolean x[M][N];,这样才能匹配每次迭代中动态扩展的N集合,避免变量维度不匹配的越界。
  • 用对象代替数组存储output是OPL main函数中处理动态索引的常用技巧,比固定长度数组灵活得多,能彻底规避索引越界问题。

备注:内容来源于stack exchange,提问作者yalan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 13:13:10