如何在使用CPLEX可调用库时将lp更改为mip

时间:2014-10-23 16:01:33

标签: optimization linear-programming cplex integer-programming

我使用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)
} 

1 个答案:

答案 0 :(得分:1)

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

   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 */