在 C++ 中向 CPLEX 模型添加约束
Adding constraints to a CPLEX model in C++
我正在使用 CPLEX 库在 C++ 中编写 MILP,但在向模型添加约束时遇到问题。代码比较长,这里只包含代码的大致结构和其中一个约束条件(以及涉及的变量)。
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <string>
#include "ilcplex/ilocplex.h"
using namespace std;
ILOSTLBEGIN
int main(){
//CPLEX environment and definition of the modelling object
IloEnv env;
IloModel model(env);
//Define the multi dimensional arrays for float and bool variables
typedef IloArray<IloBoolVarArray> BoolVar2D;
typedef IloArray<IloFloatVarArray> FloatVar2D;
typedef IloArray<IloArray<IloBoolVarArray> > BoolVar3D;
typedef IloArray<IloArray<IloFloatVarArray> > FloatVar3D;
typedef IloArray<IloArray<IloArray<IloBoolVarArray> > > BoolVar4D;
//Definition of the variable involved in the constraint
FloatVar3D U(env, I); //all alternatives except the opt-out
for(int i=0; i < I; i++){
U[i] = FloatVar2D(env, N);
for(int n=0; n < N; n++){
U[i][n] = IloFloatVarArray(env, R);
}
}
//Construction of the constraint (chi, beta, lambda, p are parameters)
for(int i =0; i < I; i++){
for(int n=0; n < N; n++){
int L_in = L[i][n];
for(int r=0; r < R; r++){
IloExpr sum(env);
sum += chi[i][n][r];
for(int l=0; l < L_in; l++){
sum += beta[i][n] * lambda[i][n][l] * p[i][n][l];
}
model.add(U[i][n][r] == sum);
}
}
}
env.end();
}
当运行代码我得到以下错误信息:
libc++abi.dylib: terminating with uncaught exception of type IloWrongUsage
有谁知道这样定义约束有什么问题吗?我尝试了同样的方法来解决更简单的问题并且它奏效了。
谢谢!
它甚至可能不是约束。正如错误文本所说,您遇到了异常,但您没有捕捉到它。因此,程序终止。
首先,您应该将代码包装在 try/catch
块中:
概念上,
int main()
{
try
{
// your variable definition and constraint code
}
catch ( IloException& e )
{
std::cout << e << std::endl;
e.end();
}
}
这应该告诉您异常的确切性质是什么。 ILOG 错误有多种原因(可能是一些无效参数、内存不足或许可证过期等),将其打印出来应该会有所帮助。
如果失败,您将不得不使用调试器单步执行代码以查看它在哪里出错以及原因。
首先,我建议使用 IloNumVarArray
而不是 IloFloatVarArray
。一般应该初始化为IloNumVarArray(const IloEnv env,IloNum lb,const IloNumArray ub,IloNumVar::Type type=ILOFLOAT)
,但是如果你的变量是连续的,并且在0到无穷大之间,那么就用:
typedef IloArray<IloNumVarArray> twoDarray;
for(int i=0; i < I; i++){
U[i] = twoDarray(env, N);
for(int n=0; n < N; n++){
U[i][n] = IloNumVarArray(env, R);
}
}
其次,chi, beta, lambda, p
是常量还是变量?如果它们是常量,那么使用 IloExpr
来总结它们是个坏主意,常规 float
类型应该可以正常工作。如果它们被声明为 IloNumArray
,那么 IloSum(const IloNumArray values)
可以为您总结 lambda 和 p:
model.add(U[i][n][r] == chi[i][n][r] + beta[i][n] * IloSum( lambda[i][n][l]* p[i][n][l]));
或者如果这不起作用通过 lambda 和 p.
定义一维 IloNumArray
的 lambda_l[l] 和 p_l[l]
感谢您的帮助,我终于弄清楚出了什么问题。基本上,变量的初始化不正确,因为我没有将它们添加到模型中。比如U变量的定义应该是这样的:
typedef IloFloatVarArray NumVar1D;
typedef IloArray<IloFloatVarArray> NumVar2D;
typedef IloArray<IloArray<IloFloatVarArray> > NumVar3D;
NumVar3D U(env);
for(int i=0; i < I; i++){
NumVar2D Ui(env);
for(int n=0; n < N; n++){
NumVar1D Uin(env);
for(int r=0; r<R; r++){
Uin.add(IloFloatVar(env));
}
Ui.add(Uin);
}
U.add(Ui);
}
更改变量的初始化后,约束正常工作,因此问题已解决。
我正在使用 CPLEX 库在 C++ 中编写 MILP,但在向模型添加约束时遇到问题。代码比较长,这里只包含代码的大致结构和其中一个约束条件(以及涉及的变量)。
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <string>
#include "ilcplex/ilocplex.h"
using namespace std;
ILOSTLBEGIN
int main(){
//CPLEX environment and definition of the modelling object
IloEnv env;
IloModel model(env);
//Define the multi dimensional arrays for float and bool variables
typedef IloArray<IloBoolVarArray> BoolVar2D;
typedef IloArray<IloFloatVarArray> FloatVar2D;
typedef IloArray<IloArray<IloBoolVarArray> > BoolVar3D;
typedef IloArray<IloArray<IloFloatVarArray> > FloatVar3D;
typedef IloArray<IloArray<IloArray<IloBoolVarArray> > > BoolVar4D;
//Definition of the variable involved in the constraint
FloatVar3D U(env, I); //all alternatives except the opt-out
for(int i=0; i < I; i++){
U[i] = FloatVar2D(env, N);
for(int n=0; n < N; n++){
U[i][n] = IloFloatVarArray(env, R);
}
}
//Construction of the constraint (chi, beta, lambda, p are parameters)
for(int i =0; i < I; i++){
for(int n=0; n < N; n++){
int L_in = L[i][n];
for(int r=0; r < R; r++){
IloExpr sum(env);
sum += chi[i][n][r];
for(int l=0; l < L_in; l++){
sum += beta[i][n] * lambda[i][n][l] * p[i][n][l];
}
model.add(U[i][n][r] == sum);
}
}
}
env.end();
}
当运行代码我得到以下错误信息:
libc++abi.dylib: terminating with uncaught exception of type IloWrongUsage
有谁知道这样定义约束有什么问题吗?我尝试了同样的方法来解决更简单的问题并且它奏效了。
谢谢!
它甚至可能不是约束。正如错误文本所说,您遇到了异常,但您没有捕捉到它。因此,程序终止。
首先,您应该将代码包装在 try/catch
块中:
概念上,
int main()
{
try
{
// your variable definition and constraint code
}
catch ( IloException& e )
{
std::cout << e << std::endl;
e.end();
}
}
这应该告诉您异常的确切性质是什么。 ILOG 错误有多种原因(可能是一些无效参数、内存不足或许可证过期等),将其打印出来应该会有所帮助。
如果失败,您将不得不使用调试器单步执行代码以查看它在哪里出错以及原因。
首先,我建议使用 IloNumVarArray
而不是 IloFloatVarArray
。一般应该初始化为IloNumVarArray(const IloEnv env,IloNum lb,const IloNumArray ub,IloNumVar::Type type=ILOFLOAT)
,但是如果你的变量是连续的,并且在0到无穷大之间,那么就用:
typedef IloArray<IloNumVarArray> twoDarray;
for(int i=0; i < I; i++){
U[i] = twoDarray(env, N);
for(int n=0; n < N; n++){
U[i][n] = IloNumVarArray(env, R);
}
}
其次,chi, beta, lambda, p
是常量还是变量?如果它们是常量,那么使用 IloExpr
来总结它们是个坏主意,常规 float
类型应该可以正常工作。如果它们被声明为 IloNumArray
,那么 IloSum(const IloNumArray values)
可以为您总结 lambda 和 p:
model.add(U[i][n][r] == chi[i][n][r] + beta[i][n] * IloSum( lambda[i][n][l]* p[i][n][l]));
或者如果这不起作用通过 lambda 和 p.
定义一维IloNumArray
的 lambda_l[l] 和 p_l[l]
感谢您的帮助,我终于弄清楚出了什么问题。基本上,变量的初始化不正确,因为我没有将它们添加到模型中。比如U变量的定义应该是这样的:
typedef IloFloatVarArray NumVar1D;
typedef IloArray<IloFloatVarArray> NumVar2D;
typedef IloArray<IloArray<IloFloatVarArray> > NumVar3D;
NumVar3D U(env);
for(int i=0; i < I; i++){
NumVar2D Ui(env);
for(int n=0; n < N; n++){
NumVar1D Uin(env);
for(int r=0; r<R; r++){
Uin.add(IloFloatVar(env));
}
Ui.add(Uin);
}
U.add(Ui);
}
更改变量的初始化后,约束正常工作,因此问题已解决。