在cplex c ++ concert api ++中处理非常大的问题而不会耗尽内存

时间:2018-03-19 18:12:42

标签: c++ cplex

我有一个非常大的LP问题,我试图使用c ++ Concei api在cplex中解决。这是我的代码的简化版本:

// Get environment
IloEnv env = model.getEnv();

// Set x variable
for(int i = 0; i <= 10000; i++){
    x.add(IloBoolVar(env));
}

// Set objective
IloNumExpr objective(env);
objective += x[0];
model.add(IloMinimize(env, objective));

// Add constraints
for (int i = 0; i < 1000000; i++) {
    IloNumExpr some_expr(env);
    for (int j = 0; j < 10000; j++){
        some_expr += x[j];
    }
    IloRange constraint(env,0,some_expr,0);
    c.add(constraint);
}

model.add(x);
model.add(c);

// store
IloCplex cplex(model);
cplex.exportModel("lpex1.lp");

当我运行它时,所使用的内存很快变得很大,导致一切都崩溃。有没有办法解决这些大问题?

1 个答案:

答案 0 :(得分:1)

考虑以下完整示例:

#include <ilcplex/ilocplex.h>
ILOSTLBEGIN

int
main (int argc, char **argv)
{
   IloEnv env;
   IloNumVarArray x(env);

   int numVars = 10000;
   int numCons = 1000000;

   if (argc == 3) {
      stringstream nvars(argv[1]);
      stringstream ncons(argv[2]);
      nvars >> numVars;
      ncons >> numCons;
   }

   // Set x variable
   for(int i = 0; i <= numVars; i++) {
      x.add(IloBoolVar(env));
   }

   // Set objective
   IloModel model(env);
   IloNumExpr objective(env);
   objective += x[0];
   model.add(IloMinimize(env, objective));

   // Add constraints
   IloRangeArray c(env);
   for (int i = 0; i < numCons; i++) {
      IloNumExpr some_expr(env);
      for (int j = 0; j < numVars; j++) {
         some_expr += x[j];
      }
      c.add(some_expr == 0.0);
      some_expr.end();
   }

   model.add(c);

   std::cout << "Memory usage after creating constraints: "
             << env.getMemoryUsage() / (1024. * 1024.)
             << " MB" << std::endl;

   env.end();
   return 0;
}  // END main

它与您的示例基本相同,只是我们使用getMemoryUsage()方法打印出我们正在使用的内存量。如果我们编译并运行它,我们得到如下输出:

$ ./test 10000 1000
Memory usage after creating constraints: 229.827 MB

请注意,这仅适用于1000个约束。如果我正确地进行数学运算,你需要1000倍的内存来构建模型,从你的示例片段开始,这将是~230 GB的RAM!这甚至不包括提取模型然后尝试解决它所需的内存量。

4 GB的计算机无法正常运行。通常,使用CPLEX Callable Library(也称为C API)将需要更小的内存占用,但您必须使用较低级别的功能。但是,在这种情况下,这也不适合您,因为您正在尝试构建一个对您的机器来说太大的模型。