2

I've solved an lp using CPLEX callable library (in VS2010). The lp is the following:

  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

The code is given beneath. Now I would like to make it an MIP (additional integrality constraints on the x's). I tried to do so by changing status = CPXlpopt (env, lp); into status = CPXmipopt (env, lp);. This does not work and I get the error 3003: not a mixed-integer problem. Does anybody know what I am missing here?

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)
} 
Nathan2055
  • 2,283
  • 9
  • 30
  • 49
J ve
  • 65
  • 8

1 Answers1

1

In your code, you are not declaring any decision variables to be integer. That's why cplex is complaining when you try to solve your problem using a MIP solver. You are doing column-wise modeling and CPXaddcols doesn't have have a parameter for the variable type, but you can use CPXcopyctype or CPXchgctype. Since you the bounds on your decision variables are all greater than 1, you are looking for the 'I' variable type, instead of 'B' for binary.

   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 */
David Nehme
  • 21,379
  • 8
  • 78
  • 117