我正试图动态引用.dat中的Excel工作表或表格,以解决CPLEX(OPL)中要解决的车辆路径中的混合整数问题。
设置为:.mod =模型,.dat =数据和MS Excel电子表格
我有一个二维数组,其中包含客户需求数据= Excel范围(为便于编码,我尚未将Excel数据格式化为表格)
.mod中的决策变量如下:
dvar布尔值x [vertices] [vertices] [scenarios]
.dat中的
SheetRead的顶点(数据,“ Table!vertices”); 和
SheetRead中的场景(数据,“尚不知道”); 可能不需要没有方案索引,一切都很好。 但是随着这种模型中客户需求的变化,我想通过更改数据库参考将其包括在内。 现在我想做的是两件事之一:
可以: 在Excel中更改电子表格,以便根据情况在.dat中获得类似的内容:
场景= 1:
SheetRead的顶点(数据,“ table-scenario-1!vertices”);
场景= 2:
SheetRead的顶点(数据,“ table-scenario-2!vertices”);
因此将电子表格更改为新的基本数据, 要么: 更改同一电子表格中的范围:
场景= 1:
SheetRead的顶点(数据,“ table!vertices-1”);
场景= 2:
SheetRead的顶点(数据,“ table!vertices-2”);
两种方法都可以。
了解如何使用分组了2D表的多个电子表格创建Excel中的3D表时,似乎更自然的方法是,使顶点始终在每个Excel电子表格中引用相同的范围,同时取决于切换电子表格/页面的方案,但我只是不知道该怎么做。
感谢您的建议。
答案 0 :(得分:1)
不幸的是,SheetConnection
的参数必须是字符串文字或ID(请参见用户手册here中的OPL语法)。同样,SheetRead
也是如此。这意味着,您不能有用于图纸连接的动态源。
正如我们在评论中讨论的那样,一种选择是向所有数据添加一个额外的索引:场景。然后,始终读取所有方案的数据,并在.mod文件中选择要实际使用的内容。
答案 1 :(得分:0)
我分享了一个示例,您可以在其中为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();
}
}