c++ - CPLEX - Adding Lazy Constraints with variables of different type lead to InvalidCutException
问题描述
I'm solving a model that has two types of variables, x[i][j] is a ILOBOOL and u[i] is a ILOFLOAT. I'm trying to add lazy constraints to this model. I've managed to correctly add lazy constraints in the following fashion:
std::stringstream name;
IloNumVar** x = new IloNumVar*[ins.n+1];
for(int i = 0; i < ins.n+1; ++i){
x[i] = new IloNumVar[ins.n];
for(int j = 0; j < ins.n; ++j){
if(ins.has_edge(i,j) || i == ins.n){
name << "x_" << i << "_" << j;
x[i][j] = IloNumVar(env,0,1,ILOBOOL, name.str().c_str());
name.str("");
}
}
}
IloNumVar* u = new IloNumVar[ins.n+1];
for(int i = 0; i < ins.n+1; ++i){
name << "u_" << i;
u[i] = IloNumVar(env,(i < ins.n) ? 1 : 0,ins.L+1,ILOFLOAT,name.str().c_str());
name.str("");
}
/*Objective function and some other non-lazy Constraints
*/
cplex.extract(model);
for(int i = 0; i < ins.n; ++i){
for(int j = 0; j < ins.n; ++j){
if(ins.has_edge(i,j)){
IloConstraint edge_con(x[i][j] + x[j][i]<= 1);
name << "edge_" <<i << "_" << j;
edge_con.setName(name.str().c_str());
name.str("");
try{
cplex.addLazyConstraint(edge_con);
}catch(IloCplex::InvalidCutException& ex){
auto con = ex.getCut();
std::cout << ex.getMessage() << " " << ex.getStatus();
std::cout << con << "\n";
}
}
}
}
This code is working fine and when I print the .lp, the lazy constraints are there. However, when I change IloConstraint edge_con(x[i][j] + x[j][i]<= 1);
to IloConstraint edge_con(x[i][j] + x[j][i] + u[j] <= 1);
I get an InvalidCutException: invalid cut -1
message. Why this exception is being thrown?
解决方案
Turning my comment into an answer:
The problem is that CPLEX does not know about the u
variables that are referenced in the lazy constraint.
If you add a regular constraint then all variables in the constraint are automatically extracted to CPLEX. For lazy constraints things are different though: the variables are not automatically extracted. So if the lazy constraint references a variable that was not used in a regular constraint or the objective before, then CPLEX will not know about this variable. This will result in failure to add the cut and you will get the exception you observed.
To fix this, explicitly add the u
variables to the problem using
for (i = 0; i < ins.n+1; ++i)
model.add(u[i]);
(and maybe do the same for the x
variables)
推荐阅读
- javascript - 我想通过单击按钮停止传播...在此代码中,我可以通过复选框执行操作,但我想通过单击按钮执行相同的操作
- javascript - 如何在java脚本中合并两个数组值
- python - 如何将纯文本转换为可解析文本(每个单词之间有百分比符号)?
- python - 如何用一个函数替换字符串数据框中的多个字符
- firebase - 如何查看firestore中快照之间的变化?| 扑
- google-cloud-platform - Cloud Shell 技术错误 - 有没有其他人经历过这个?
- php - 使用 php从标签中获取 URL
- c - C中#define的逆向
- react-native - 如何在 React Native 中创建具有复杂形状的底部标签栏
- python - ImportError:动态模块未使用 docker 定义模块导出功能