2

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

1 回答 1

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 */
于 2014-10-23T19:22:28.323 回答