ILOG CPLEX / OPL 动态 Excel sheet 引用
ILOG CPLEX / OPL dynamic Excel sheet referencing
我正在尝试在 .dat 中动态引用 Excel 工作表或 tables 以解决我试图在 CPLEX (OPL) 中解决的车辆路线规划中的混合整数问题。
设置是:.mod = model,.dat = 数据和 MS Excel 电子表格
我有一个二维数组,客户需求数据 = Excel 范围(为了编码方便,我还没有将 excel 数据格式化为 table)
.mod 中的决策变量如下所示:
dvar boolean x[顶点][顶点][场景]
在 .dat 中:
来自 SheetRead 的顶点(数据,"Table!vertices");
和
来自 SheetRead 的场景(数据,"dont know how to yet"); 这可能不需要
没有场景索引一切都很好。
但随着客户需求在 model 中的变化,我想通过更改数据库引用来包含它。
现在我想做的是两件事之一:
或者:
更改 Excel 中的电子表格,以便根据情况在 .dat 中得到类似的内容:
情景=1:
来自 SheetRead 的顶点(数据,"table-scenario-1!vertices");
情景=2:
来自 SheetRead 的顶点(数据,"table-scenario-2!vertices");
因此更改新基础数据的电子表格,
要么:
更改同一电子表格中的范围:
情景=1:
来自 SheetRead 的顶点(数据,"table!vertices-1");
情景=2:
来自 SheetRead 的顶点(数据,"table!vertices-2");
两种方式都可以。
了解 Excel 中的 3D 表格是如何使用多个电子表格创建的,并将 2D 表格分组,更自然的方法似乎是,让每个 Excel 电子表格中的顶点始终引用相同的范围,同时根据场景切换 spreadsheet/page,但我不知道如何切换。
感谢您的建议。
不幸的是,SheetConnection
的参数必须是字符串文字或 Id(请参阅用户手册中的 OPL 语法 here)。 SheetRead
也是如此。这意味着,您不能为 sheet 连接提供动态源。
正如我们在评论中讨论的那样,一种选择是为所有数据添加一个额外的索引:场景。然后始终读取所有场景的数据,并在 .mod 文件中 select 您想要实际使用的内容。
在 https://www.ibm.com/developerworks/community/forums/html/topic?id=5af4d332-2a97-4250-bc06-76595eef1ab0&ps=25 我分享了一个示例,您可以在其中为 Excel 文件设置动态名称。与您可以拥有动态范围的方式相同,诀窍是使用流量控制。
sub.mod
float maxOfx = 2;
string fileName=...;
dvar float x;
maximize x;
subject to {
x<=maxOfx;
}
execute
{
writeln("filename= ",fileName);
}
然后是主模型
main {
var source = new IloOplModelSource("sub.mod");
var cplex = new IloCplex();
var def = new IloOplModelDefinition(source);
var opl = new IloOplModel(def,cplex);
for(var k=11;k<=20;k++)
{
var opl = new IloOplModel(def,cplex);
var data2= new IloOplDataElements();
data2.fileName="file"+k;
opl.addDataSource(data2);
opl.generate();
if (cplex.solve()) {
writeln("OBJ = " + cplex.getObjValue());
} else {
writeln("No solution");
}
opl.postProcess();
opl.end();
}
}
我正在尝试在 .dat 中动态引用 Excel 工作表或 tables 以解决我试图在 CPLEX (OPL) 中解决的车辆路线规划中的混合整数问题。
设置是:.mod = model,.dat = 数据和 MS Excel 电子表格
我有一个二维数组,客户需求数据 = Excel 范围(为了编码方便,我还没有将 excel 数据格式化为 table)
.mod 中的决策变量如下所示:
dvar boolean x[顶点][顶点][场景]
在 .dat 中:
来自 SheetRead 的顶点(数据,"Table!vertices"); 和
来自 SheetRead 的场景(数据,"dont know how to yet"); 这可能不需要
没有场景索引一切都很好。 但随着客户需求在 model 中的变化,我想通过更改数据库引用来包含它。 现在我想做的是两件事之一:
或者: 更改 Excel 中的电子表格,以便根据情况在 .dat 中得到类似的内容:
情景=1:
来自 SheetRead 的顶点(数据,"table-scenario-1!vertices");
情景=2:
来自 SheetRead 的顶点(数据,"table-scenario-2!vertices");
因此更改新基础数据的电子表格, 要么: 更改同一电子表格中的范围:
情景=1:
来自 SheetRead 的顶点(数据,"table!vertices-1");
情景=2:
来自 SheetRead 的顶点(数据,"table!vertices-2");
两种方式都可以。
了解 Excel 中的 3D 表格是如何使用多个电子表格创建的,并将 2D 表格分组,更自然的方法似乎是,让每个 Excel 电子表格中的顶点始终引用相同的范围,同时根据场景切换 spreadsheet/page,但我不知道如何切换。
感谢您的建议。
不幸的是,SheetConnection
的参数必须是字符串文字或 Id(请参阅用户手册中的 OPL 语法 here)。 SheetRead
也是如此。这意味着,您不能为 sheet 连接提供动态源。
正如我们在评论中讨论的那样,一种选择是为所有数据添加一个额外的索引:场景。然后始终读取所有场景的数据,并在 .mod 文件中 select 您想要实际使用的内容。
在 https://www.ibm.com/developerworks/community/forums/html/topic?id=5af4d332-2a97-4250-bc06-76595eef1ab0&ps=25 我分享了一个示例,您可以在其中为 Excel 文件设置动态名称。与您可以拥有动态范围的方式相同,诀窍是使用流量控制。
sub.mod
float maxOfx = 2;
string fileName=...;
dvar float x;
maximize x;
subject to {
x<=maxOfx;
}
execute
{
writeln("filename= ",fileName);
}
然后是主模型
main {
var source = new IloOplModelSource("sub.mod");
var cplex = new IloCplex();
var def = new IloOplModelDefinition(source);
var opl = new IloOplModel(def,cplex);
for(var k=11;k<=20;k++)
{
var opl = new IloOplModel(def,cplex);
var data2= new IloOplDataElements();
data2.fileName="file"+k;
opl.addDataSource(data2);
opl.generate();
if (cplex.solve()) {
writeln("OBJ = " + cplex.getObjValue());
} else {
writeln("No solution");
}
opl.postProcess();
opl.end();
}
}