【问题标题】:Adding constraints to a CPLEX model in C++在 C++ 中向 CPLEX 模型添加约束
【发布时间】:2015-11-23 12:24:23
【问题描述】:

我正在使用 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

有谁知道以这种方式定义约束有什么问题?我尝试了同样的方法来解决更简单的问题,它奏效了。

谢谢!

【问题讨论】:

    标签: c++ netbeans linear-programming cplex


    【解决方案1】:

    它甚至可能不是约束。正如错误文本所说,你得到了一个异常,但你没有捕捉到它。因此,程序终止。

    首先,您应该将代码包装在 try/catch 块中:

    从概念上来说,

    int main()
    {
        try
        {
            // your variable definition and constraint code
        }
        catch ( IloException& e )
        {
            std::cout << e << std::endl;
            e.end();
        }
    }
    

    这应该告诉您异常的确切性质是什么。 ILOG 错误有多种原因(可能是一些无效参数、内存不足或许可证过期等),打印出来应该会有所帮助。

    如果失败,您将不得不使用调试器单步执行您的代码,以查看它在哪里中断以及为什么。

    【讨论】:

      【解决方案2】:

      首先,我建议使用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's 那么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]。

      【讨论】:

        【解决方案3】:

        感谢您的帮助,我终于弄清楚出了什么问题。基本上,变量的初始化是不正确的,因为我没有将它们添加到模型中。比如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);
        }
        

        更改变量的初始化后,约束正常工作,因此问题得到解决。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-05
          • 1970-01-01
          • 1970-01-01
          • 2018-10-10
          相关资源
          最近更新 更多