如何更新主 CPLEX 中的数组数据

How to update array data in main CPLEX

我正在尝试使用 OPL 在 CPLEX 12.10 中创建模型。

到目前为止我所做的是创建模型并编写 flow-control/main 部分以生成新模型。我在更新新数组中的值时遇到问题(每次迭代时数组的维度都会增加)。我有以下参数,其大小取决于 3 组的值:

我在流程控制部分有如下代码:

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.numSet1=sizenumSet1; 
        dat.numSet2=sizenumSet2; 
        dat.numSet3=sizenumSet3; 
        opl.addDataSource(dat); 
        opl.generate(); 
        for (var k in sizenumSet1){
            //random values for Par1[Set1]
            dat.Par1[k]= 10 + Opl.rand(100);
            writeln(Par1);
            //random values for Par2[Set1][Set2] 
            for (var m in sizenumSet2){
                dat.Par2[k][m]= 1 + Opl.rand(5);
                writeln(Par2);
                    for (var j in sizenumSet3) {
                        //random values for Par4[Set1][Set2][Set3]
                        dat.Par4[k][m][j] = 1 + Opl.rand(10);
                        writeln(Par4);
            }
        }    
            //random values for Par3[Set1]
            dat.Par3[k]= 1 + Opl.rand(5);
            writeln(Par3);
        }  
        if (MyCplex.solve()) {
         writeln("Solution: ", MyCplex.getObjValue(),
        " / sizeSet1: ", sizenumSet1,
        " / sizeSet2: ", sizenumSet2,
        " / sizeSet3: ", sizenumSet3,
        " / time: ", MyCplex.getCplexTime());
        }    
        opl.end(); 
        MyCplex.end(); 
        }
    }
    }         
}

运行这段代码我得到以下错误:

Scripting runtime error: Index out of bound for array "Par1", "toString".

所以我有两个问题:

  1. 如何解决这个错误?
  2. 如何根据集合的大小更新 Par1 中的值?

谢谢

更新代码:

sub.mod

//set
{int} subrow = ...;
{int} subcol = ...;
int y[subrow][subcol]=...;

//preprocessing
execute{
    writeln("y=",y);
}

//decisional variables
dvar float x;

//model
maximize x;
subject to {
  x<=sum(i in subrow, j in subcol) y[i][j];
}

//postprocessing
execute{
    writeln("x=",x);
}

main.mod

{int} row={};
{int} col={};
int numrow = 2;
int numcol = 2;
int ar[1..numrow][1..numcol];

main {
  var source = new IloOplModelSource("sub.mod"); 
  var cplex = new IloCplex(); 
  var def = new IloOplModelDefinition(source);     
  for (var dimrow=1; dimrow<=2; dimrow+=1){ 
    for (var dimcol=1; dimcol<=2; dimcol+=1){ 
        var opl = new IloOplModel(def,cplex); 
        var data2 = new IloOplDataElements(); 
      for(var i=1; i<=dimrow; i+=1){ 
         for(var j=1; j<=dimcol; j+=1){ 
            data2.subrow = thisOplModel.row; 
            data2.subrow.add(dimrow); 
            data2.subcol = thisOplModel.col; 
            data2.subcol.add(dimcol); 
            data2.y = thisOplModel.ar; 
            data2.y[i][j] = Opl.rand(10); 
            } 
        } 
    }   
  }
        opl.addDataSource(data2);
        opl.generate(); 
        if (cplex.solve()) { 
            writeln("OBJ = " + cplex.getObjValue()); 
        } else { 
            writeln("No solution");
        } 
        data2.end(); 
        opl.end();  
} 

最后我总是得到一个在 numrow = 2 和 numcol = 2 中声明的维度矩阵。我无法更改该值。如果我更改它并且它与 "for" cyles 中的那些不对齐,那么我有一个错误(越界)。

来自https://www.linkedin.com/pulse/how-opl-alex-fleischer/

的一个小例子

Change a 2D array and solve again

sub.mod

int y[1..2][1..2]=...;

execute
{
writeln("y=",y);
}

dvar float x;

maximize x;
subject to {
  x<=sum(i in 1..2, j  in 1..2) y[i][j];
}

然后在另一个 .mod 文件中

int a[1..2][1..2];

main {
  var source = new IloOplModelSource("sub.mod");
  var cplex = new IloCplex();
  var def = new IloOplModelDefinition(source);



  for(var k=11;k<=15;k++)
  {
  var opl = new IloOplModel(def,cplex);



  var data2= new IloOplDataElements();

  data2.y=thisOplModel.a;
  data2.y[1][1]=k;
  opl.addDataSource(data2);

  opl.generate();

  if (cplex.solve()) {
     writeln("OBJ = " + cplex.getObjValue());
  } else {
     writeln("No solution");
  }
  data2.end();
 opl.end();


}  

}

给予

y= [[11 0]
         [0 0]]
OBJ = 11
y= [[12 0]
         [0 0]]
OBJ = 12
y= [[13 0]
         [0 0]]
OBJ = 13
y= [[14 0]
         [0 0]]
OBJ = 14
y= [[15 0]
         [0 0]]
OBJ = 15

并在您发表评论后更新

sub.mod

{int} row=...;
    {int} col=...;

    int y[row][col]=...;

execute
{
writeln("y=",y);
}

dvar float x;

maximize x;
subject to {
   x<=sum(i in row, j in col) y[i][j];
}

execute
{
writeln("x=",x);
}

然后是主要的 model

{int} set1={};
{int} set2={};
int ar[1..11][1..11];

main {
  var source = new IloOplModelSource("sub.mod");
  var cplex = new IloCplex();
  var def = new IloOplModelDefinition(source);


  for(var k=1;k<=5;k++)
  {
  var opl = new IloOplModel(def,cplex);

  var data2= new IloOplDataElements();

data2.row=thisOplModel.set1;
data2.row.add(k);
data2.row.add(k+1);
data2.col=thisOplModel.set2;
data2.col.add(2*k);
data2.col.add(2*k+1);
data2.y=thisOplModel.ar;
for(var a in data2.row) for(var b in data2.col) data2.y[a][b]=a+b;
  opl.addDataSource(data2);
  opl.generate();

  if (cplex.solve()) {
     writeln("OBJ = " + cplex.getObjValue());
  } else {
     writeln("No solution");
  }
data2.end();
 opl.end();


}  

}

你可以随心所欲地扩展矩阵。 让我更新我的例子:

sub.mod

{int} row=...;
    {int} col=...;

int y[row][col]=...;

execute
{
  writeln("row=",row);
  writeln("col=",col);
//writeln("y=",y);
}

dvar float x;

maximize x;
subject to {
   x<=sum(i in row, j in col) y[i][j];
}

execute
{
writeln("x=",x);
}

然后

{int} set1={};
{int} set2={};
int ar[1..11][1..11];

main {
  var source = new IloOplModelSource("sub.mod");
  var cplex = new IloCplex();
  var def = new IloOplModelDefinition(source);


  for(var k=1;k<=5;k++)
  {
  var opl = new IloOplModel(def,cplex);

  var data2= new IloOplDataElements();

data2.row=thisOplModel.set1;

data2.row.add(k+2);
data2.row.add(k+3);
data2.col=thisOplModel.set2;
if (k!=1) data2.col.remove(Opl.first(data2.col));
data2.col.add(2*k);
data2.col.add(2*k+1);
data2.y=thisOplModel.ar;
for(var a in data2.row) for(var b in data2.col) data2.y[a][b]=a+b;
  opl.addDataSource(data2);
  opl.generate();

  if (cplex.solve()) {
     writeln("OBJ = " + cplex.getObjValue());
  } else {
     writeln("No solution");
  }
data2.end();
 opl.end();


}  

}

你得到

row= {3 4}
col= {2 3}
OBJ = 24
row= {3 4 5}
col= {3 4 5}
OBJ = 72
row= {3 4 5 6}
col= {4 5 6 7}
OBJ = 160
row= {3 4 5 6 7}
col= {5 6 7 8 9}
OBJ = 300
row= {3 4 5 6 7 8}
col= {6 7 8 9 10 11}
OBJ = 504

并且可以看到矩阵越来越大