Как обновить массив данных в основном CPLEX - PullRequest
0 голосов
/ 11 февраля 2020

Я пытаюсь создать модель в CPLEX 12.10, используя OPL.

То, что я делал до сих пор, - это создание модели и написание части управления потоком / основной части для генерации новых моделей. У меня проблема с обновлением значений в новом массиве (размерность массивов увеличивается с каждой итерацией). У меня есть следующие параметры, размер которых зависит от значения 3 комплектов:

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

У меня есть следующий код в части управления потоком:

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», то у меня будет ошибка (вне пределов).

Ответы [ 2 ]

0 голосов
/ 14 февраля 2020

вы можете вырастить матрицу, как вам нравится. Позвольте мне обновить мой пример:

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

, и вы можете увидеть, что матрица становится все больше и больше

0 голосов
/ 11 февраля 2020

небольшой пример из https://www.linkedin.com/pulse/how-opl-alex-fleischer/

Изменить двумерный массив и решить снова

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);
}

а затем основная модель

{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();


}  

}
...