【问题标题】:Change array dimension when generating a new model CPLEX OPL生成新模型 CPLEX OPL 时更改数组维度
【发布时间】:2020-02-07 09:18:46
【问题描述】:

我有一个要在 IBM CPLEX Optimization Studio 12.10 中实现的优化模型。 我在 OPL 中编写了模型代码,第一个实现正在运行。我现在想做的是多次迭代模型,以查看解析时间如何根据参数的维度而变化。

在 .mod 文件中我定义了三组:

  • int numSet1=...;
  • int numSet2=...;
  • int numSet3=...;
  • 范围 Set1 = 1..numSet1;
  • 范围 Set2 = 1..numSet2;
  • 范围 Set3 = 1..numSet3;

还有四个参数:

  • float Par1[Set1]=...;
  • float Par2[Set1][Set2]=...;
  • float Par3[Set1]=...;
  • float Par4[Set1][Set2][Set3]=...;

在 .dat 文件中,我为这些集合和参数定义了初始值。

我现在想做的是在流控制中定义一个代码,允许我更改集合的尺寸,从而更改参数的尺寸,并节省每个分辨率的分辨率时间:

main {
    var mod = thisOplModel.modelDefinition; 
    var dat = thisOplModel.dataElements; 
    for (var sizenumSet1 = 2; sizenumSet1 <= 10; sizenumSet1 += 2) {
    for (var sizenumSet2 = 1; sizenumSet2 <= 5; sizenumSet2 +=1) {
      for (var sizenumSet3 = 1; sizenumSet3 <=5; sizenumSet3 +=1) {
        var MyCplex = new IloCplex(); 
        var opl = new IloOplModel(mod, MyCplex); 
        dat.changenumSet1=sizenumSet1; 
        dat.changenumSet2=sizenumSet2; 
        dat.changenumSet3=sizenumSet3; 
        opl.addDataSource(dat); 
        opl.generate(); 
        if (MyCplex.solve()) {
         writeln("Solution: ", MyCplex.getObjValue(),
        " / sizeSet1: ", sizenumSet1,
        " / sizeSet2: ", sizenumSet2,
        " / sizeSet3: ", sizenumSet3,
        " / time: ", MyCplex.getCplexTime());
        }    
        opl.end(); 
        MyCplex.end(); 
        }
    }
    }         
}

当我启动此代码时,我得到以下错误列表:

  • main 执行失败。处理 OPL 模型失败
  • 数组 Par4(1)(1):3 的索引超出范围
  • 脚本运行时错误:(在生成中)处理 OPL 模型失败

我该如何解决这个问题? 感谢您的帮助。

【问题讨论】:

    标签: multidimensional-array cplex opl


    【解决方案1】:

    dat.changenumSet1=sizenumSet1;
    dat.changenumSet2=sizenumSet2;
    dat.changenumSet3=sizenumSet3;
    

    您正在更改错误的元素。你应该改变

    dat.numSet1=sizenumSet1;
    dat.numSet2=sizenumSet2;
    dat.numSet3=sizenumSet3;
    

    此外,您似乎缺少对 Par 数组的更新。这些数组在每次迭代中都会变大,因此需要为它们提供更多的数据。

    【讨论】:

    • 嗨!谢谢您的回答。如何更新数组和其中的值?我尝试使用 for 循环,例如 for (x in numSet1){ dat.Par1[x] = 1 + Opl.rand(10); writeln(Par1);但现在错误是“脚本运行时错误:数组“Par1”、“toString”的索引超出范围。如果我写“Par1=1 + Opl.rand(10);”而不是“dat.Par1[x] = 1 + Opl.rand(10);”错误是“脚本运行时错误:未知变量“Par1”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    • 2020-08-20
    相关资源
    最近更新 更多