C++ CPLEX-添加具有不同类型变量的惰性约束会导致InvalidCutException
我在解一个有两种变量的模型,x[I][j]是一个ILOBOOL,u[I]是一个ILOFLOAT。我正在尝试向这个模型添加惰性约束。我成功地以以下方式正确添加了惰性约束:C++ CPLEX-添加具有不同类型变量的惰性约束会导致InvalidCutException,c++,cplex,C++,Cplex,我在解一个有两种变量的模型,x[I][j]是一个ILOBOOL,u[I]是一个ILOFLOAT。我正在尝试向这个模型添加惰性约束。我成功地以以下方式正确添加了惰性约束: 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.
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";
}
}
}
}
std::stringstream名称;
IloNumVar**x=新的IloNumVar*[ins.n+1];
对于(int i=0;i name将我的评论转化为答案:
问题是CPLEX不知道惰性约束中引用的u
变量
如果添加常规约束,则约束中的所有变量都会自动提取到CPLEX。但对于惰性约束,情况有所不同:变量不会自动提取。因此,如果惰性约束引用了以前未在常规约束或目标中使用的变量,则CPLEX将不知道ab输出此变量。这将导致添加切割失败,并且您将得到观察到的异常
要解决此问题,请使用显式地将u
变量添加到问题中
for (i = 0; i < ins.n+1; ++i)
model.add(u[i]);
for(i=0;i
(对x
变量也可以这样做)你能展示你的完整代码吗?在添加惰性约束之前,u
在模型中使用了吗?它对调用for(i=0;i
?你好@DanielJunglas谢谢你的提示!做model.add(u[i]);在初始化之后(我也做了model.add(x[I][j]);以及)成功了!你知道为什么会这样吗?为了添加惰性约束,CPLEX必须知道这些约束中出现的变量。这意味着,它们必须已被提取到CPLEX。如果变量出现在常规约束中,则会自动发生这种情况。对于惰性约束,情况并非如此。如果在惰性约束中使用变量培训之前未被引用,然后您必须显式地add()
向CPLEX报告这些培训。