如何更新主 CPLEX 中的数组数据
How to update array data in main CPLEX
我正在尝试使用 OPL 在 CPLEX 12.10 中创建模型。
到目前为止我所做的是创建模型并编写 flow-control/main 部分以生成新模型。我在更新新数组中的值时遇到问题(每次迭代时数组的维度都会增加)。我有以下参数,其大小取决于 3 组的值:
- float Par1[Set1]=...;
- float Par2[Set1][Set2]=...;
- 浮动 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".
所以我有两个问题:
- 如何解决这个错误?
- 如何根据集合的大小更新 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
并且可以看到矩阵越来越大
我正在尝试使用 OPL 在 CPLEX 12.10 中创建模型。
到目前为止我所做的是创建模型并编写 flow-control/main 部分以生成新模型。我在更新新数组中的值时遇到问题(每次迭代时数组的维度都会增加)。我有以下参数,其大小取决于 3 组的值:
- float Par1[Set1]=...;
- float Par2[Set1][Set2]=...;
- 浮动 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".
所以我有两个问题:
- 如何解决这个错误?
- 如何根据集合的大小更新 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
并且可以看到矩阵越来越大