CPLEX c++接口:如何获取违反约束的索引

CPLEX C++ Interface: How to get the index of a violated constraint?

本文关键字:约束 索引 获取 接口 c++ 何获取 CPLEX      更新时间:2023-10-16

我尝试用c++中的IBM ILOG CPLEX求解一个整数线性程序(ILP)。求解器指出问题是不可行的,并指出违反约束的指标。我的问题是关于c++中这个约束的识别和分析。

分析约束的手动方法是使用extractModel函数将问题导出到一个文本文件,并在该文件中查找违反的约束。

最好,我想获得c++中违反约束的索引,并获得尽可能多的关于此冲突的信息。

目前,我正在使用冲突精炼器,但没有从中获得任何有用的信息。具体来说,我保留了我添加到模型中的所有约束的IloRangeArray,为此数组调用refineConflict,然后使用函数getConflict来查询(可能)违反的约束。结果是,我添加的所有约束都可能被违反,而且没有任何约束被证明是违反的。

我如何访问错误消息中报告的一个约束的索引,该错误消息指出问题是不可行的?

还有,我是否错误地使用了冲突精炼器?例如,当我在一个单独的数组中复制我添加到模型中的约束时,我是否做错了什么?(Cplex中某些类的复制构造函数和赋值操作符似乎有我不理解的非标准行为。)

我没有尝试使用冲突精炼器API。也许应该调查一下……但我在独立的交互式CPLEX中经常使用冲突精炼器。我不知道在你自己的代码中保留约束副本的任何问题-我以前在CPLEX中做过。与c++一致。这可能是对冲突精炼器功能的概念性误解…

请记住,只有一个可识别的不可行的约束是非常罕见的。更常见的情况是,存在一组不能同时满足的约束,但如果删除了其中任何一个约束,那么其余的约束就可行了。这通常被称为"不可约不可行的集合"。

考虑以下三个约束条件:

a >= b + 1
b >= c + 1
c >= a + 1

显然,这三个约束不能同时满足,但拿走其中任何一个,其他两个就可以了。在某些情况下,很难确定哪个约束是错误的,这实际上取决于对问题及其模型的更深入理解。

无论如何,尝试将模型导出为LP, MPS或SAV格式文件,并将其读入独立的CPLEX优化器。然后优化它——它也应该失败,报告不可行性。然后运行冲突精炼器,然后显示计算出的(不可约的)不可行的集合:

read fred.lp
optimize
conflict
display conflict all

我发现MPS文件在保留问题的全部精度方面更好,并且可能更便于与其他求解器一起尝试,但LP文件更易于人类阅读。SAV文件格式应该是CPLEX在内存中的最准确的副本,但它非常不透明,而且是特定于CPLEX的。如果您的问题显然是不可行的,LP格式可能更好,但如果问题是边缘不可行的,您可能会从LP文件中获得不同的行为。如果你给所有的变量和约束都命名,这可能会对你有很大的帮助。也许只是在调试版本中进行命名,或者添加一个标志来控制是否进行额外的命名。