无法使用 ILOG CP 的 C++ API 访问决策变量

Cannot access decision variables using the C++ API for ILOG's CP

本文关键字:API C++ 访问 决策 变量 CP ILOG      更新时间:2023-10-16

好的,我花了过去 2 个小时试图完成这项工作,但我的想法已经用完了。

我开发了一个 OPL 模型,就像 ILOG 附带的示例一样。我正在做的是通过C++接口程序加载数据集+模型,最后我想要的是后处理解决方案,将其保存到文件中,将其发送给其他求解器等。

该模型工作得很好,使用opl.printSolution()完美地打印解决方案。但是,当我尝试手动访问数据时 结构似乎缺少信息,我不知道为什么。

我感兴趣的变量在模型中定义如下:

tuple Mode {
int opId;
int mch;
int pt;
};
{Mode}      Modes = ...;
dvar interval modes[md in Modes] optional size md.pt;

成功返回cp.solve()后,我尝试使用以下代码解析数据:

IloIntervalVarMap modes = opl.getElement("modes").asIntervalVarMap();
IloTupleSet Modes = opl.getElement("Modes").asTupleSet();

int index = 0;
for (IloTupleIterator iter(Modes); iter.ok(); ++iter){
IloTuple t = *iter;
printf("Tuple Values [%d,%d,%d]n",
(int) t.getIntValue((IloInt) 0),
(int) t.getIntValue((IloInt) 1),
(int) t.getIntValue((IloInt) 2));

//Fetch the mode in solution to find out what is its deal
int t_uid = (int) t.getIndex();
IloIntervalVar t_val = modes.get(t);
float t_start = (float) t_val.getStartMin();
float t_end = (float) t_val.getEndMin();
bool t_present = (bool) t_val.isPresent();
float t_size = (float) t_val.getSizeMin();
printf("t Map Values %f %f %f n", t_start, t_end, t_size);
if (t_val.isPresent()){
printf("Found Present Mode - Index %dn", t_uid);
}
}

当我使用opl.printSolution()打印解决方案时,modes如下所示:

modes = [<0 0 0 0> <1 0 123 123> <0 0 0 0> <1 123 253 130>
<0 0 0 0> <0 0 0 0> <1 581 731 150>
<0 0 0 0> <0 0 0 0> <0 0 0 0> <1 253 398 145>
<1 174 388 214> <0 0 0 0> <1 398 464 66>
<0 0 0 0> <0 0 0 0> <1 481 576 95>
<0 0 0 0> <1 500 620 120> <0 0 0 0>
<1 87 174 87> <0 0 0 0> <0 0 0 0> <1 245 350 105>
<0 0 0 0> <0 0 0 0> <1 260 360 100>
<0 0 0 0> <0 0 0 0> <1 398 563 165>
<1 0 87 87> <0 0 0 0> <0 0 0 0> <1 87 260 173>
<1 350 495 145> <0 0 0 0> <0 0 0 0>
<1 87 257 170> <1 388 516 128> <0 0 0 0>
<0 0 0 0> <1 516 581 65> <0 0 0 0>
<0 0 0 0> <1 581 681 100> <0 0 0 0>
<0 0 0 0> <0 0 0 0> <1 581 746 165>
<1 253 398 145> <0 0 0 0> <0 0 0 0>
<1 475 598 123> <0 0 0 0> <0 0 0 0>
<1 620 740 120> <0 0 0 0> <0 0 0 0>
<0 0 0 0> <1 701 751 50> <0 0 0 0>
<1 0 145 145> <1 598 722 124> <0 0 0 0>
<0 0 0 0> <0 0 0 0> <1 145 323 178>
<1 360 500 140> <0 0 0 0> <0 0 0 0>
<1 0 245 245> <0 0 0 0> <1 257 481 224>
<0 0 0 0> <0 0 0 0> <1 323 501 178>
<1 551 701 150> <0 0 0 0> <0 0 0 0>
<1 145 295 150> <1 295 475 180> <0 0 0 0>
<0 0 0 0> <1 501 551 50> <1 576 726 150>
<0 0 0 0>];

但是,当我查询结构时,访问的所有intervalvar变量似乎都被重置了。t_val.isPresent()方法总是返回 false,而开始和结束时间有次要异常设置为 -2(当我查询 MinStart 时间时,异常值为 0......它们的大小(tval.getSizeMin/Max()(是正确的。

我做错了什么还是错误或其他什么?

您似乎获得了模型中变量的域/值,而不是 CP 引擎中的变量。 我认为你应该使用: IloCP::isPresent(IloIntervalVar x( IloCP::getStartMin(IloIntervalVar x( 等。 访问解决方案值