【问题标题】:How to change lp to mip when using CPLEX callable library使用 CPLEX 可调用库时如何将 lp 更改为 mip
【发布时间】:2014-10-23 16:01:32
【问题描述】:

我已经使用 CPLEX 可调用库(在 VS2010 中)解决了一个 lp。 lp如下:

  Maximize
   obj: x1 + 2 x2 + 3 x3
  Subject To
   c1: - x1 + x2 + x3 <= 20
   c2: x1 - 3 x2 + x3 <= 30
  Bounds
   0 <= x1 <= 40
  End

代码如下。现在我想让它成为 MIP(对 x 的附加完整性约束)。我试图通过将status = CPXlpopt (env, lp); 更改为status = CPXmipopt (env, lp); 来做到这一点。这不起作用,我收到错误3003: not a mixed-integer problem。有人知道我在这里缺少什么吗?

int main ()
{
   /* Declare and allocate space for the variables and arrays where we
      will store the optimization results including the status, objective
      value, variable values, dual values, row slacks and variable
      reduced costs. */

   int      solstat;
   double   objval;
   double   *x = NULL;
   double   *pi = NULL;
   double   *slack = NULL;
   double   *dj = NULL;


   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           status = 0;
   int           i, j;
   int           cur_numrows, cur_numcols;

   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   /* Turn on output to the screen */
   status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON);

   /* Turn on data checking */
   status = CPXsetintparam (env, CPX_PARAM_DATACHECK, CPX_ON);

   /* Create the problem. */
   lp = CPXcreateprob (env, &status, "lpex1");

   /* Now populate the problem with the data. */
    #define NUMROWS    2
    #define NUMCOLS    3
    #define NUMNZ      6

   /* To populate by column, we first create the rows, and then add the columns.  */

   int      status    = 0;
   double   obj[NUMCOLS];
   double   lb[NUMCOLS];
   double   ub[NUMCOLS];
   char     *colname[NUMCOLS];
   int      matbeg[NUMCOLS];
   int      matind[NUMNZ];
   double   matval[NUMNZ];
   double   rhs[NUMROWS];
   char     sense[NUMROWS];
   char     *rowname[NUMROWS];

   CPXchgobjsen (env, lp, CPX_MAX);  /* Problem is maximization */

   /* Now create the new rows.  First, populate the arrays. */

   rowname[0] = "c1";
   sense[0]   = 'L';
   rhs[0]     = 20.0;

   rowname[1] = "c2";
   sense[1]   = 'L';
   rhs[1]     = 30.0;

   status = CPXnewrows (env, lp, NUMROWS, rhs, sense, NULL, rowname);
   if ( status )   goto TERMINATE;

   /* Now add the new columns.  First, populate the arrays. */

       obj[0] = 1.0;      obj[1] = 2.0;           obj[2] = 3.0;

    matbeg[0] = 0;     matbeg[1] = 2;          matbeg[2] = 4;

    matind[0] = 0;     matind[2] = 0;          matind[4] = 0;
    matval[0] = -1.0;  matval[2] = 1.0;        matval[4] = 1.0;

    matind[1] = 1;     matind[3] = 1;          matind[5] = 1;
    matval[1] = 1.0;   matval[3] = -3.0;       matval[5] = 1.0;

    lb[0] = 0.0;       lb[1] = 0.0;            lb[2] = 0.0;
    ub[0] = 40.0;      ub[1] = CPX_INFBOUND;   ub[2] = CPX_INFBOUND;

   colname[0] = "x1"; colname[1] = "x2";      colname[2] = "x3";

   status = CPXaddcols (env, lp, NUMCOLS, NUMNZ, obj, matbeg, matind, matval, lb, ub, colname);


   /* Optimize the problem and obtain solution. */

   status = CPXlpopt (env, lp);   

   cur_numrows = CPXgetnumrows (env, lp);
   cur_numcols = CPXgetnumcols (env, lp);

   x = (double *) malloc (cur_numcols * sizeof(double));
   slack = (double *) malloc (cur_numrows * sizeof(double));
   dj = (double *) malloc (cur_numcols * sizeof(double));
   pi = (double *) malloc (cur_numrows * sizeof(double));

   status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);

   /* Write the output to the screen. */

   printf ("\nSolution status = %d\n", solstat);
   printf ("Solution value  = %f\n\n", objval);

   for (i = 0; i < cur_numrows; i++) {
      printf ("Row %d:  Slack = %10f  Pi = %10f\n", i, slack[i], pi[i]);
   }

   for (j = 0; j < cur_numcols; j++) {
      printf ("Column %d:  Value = %10f  Reduced cost = %10f\n",
              j, x[j], dj[j]);
   }

   /* Finally, write a copy of the problem to a file. */

   status = CPXwriteprob (env, lp, "lpex1.lp", NULL);

   /* Free up the solution */

    ...  (additional code to free up the solution)...

    return(status)
} 

【问题讨论】:

    标签: optimization linear-programming cplex integer-programming


    【解决方案1】:

    在您的代码中,您没有将任何决策变量声明为整数。这就是为什么当您尝试使用 MIP 求解器解决问题时 cplex 会抱怨的原因。您正在进行按列建模,而 CPXaddcols 没有变量类型的参数,但您可以使用 CPXcopyctypeCPXchgctype。由于您的决策变量的界限都大于 1,因此您正在寻找“I”变量类型,而不是二进制的“B”。

       char     *ctype;
       ctype = (char *) malloc(cur_numcols * sizeof(char);
    
       for (j = 0; j < cur_numcols; j++) {
            ctype[j] = 'I';
       }
    
       status = CPXcopyctype(env, lp, ctype);
       /* verify status */
    
       status = CPXmipopt (env, lp);
       /* verify status */
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      相关资源
      最近更新 更多