예제 #1
0
/** Apply a predefined parameter settings.
 * \param env     The environment to which the predefined setting is applied.
 * \param setting Index of the setting to apply.
 */
static void
applySettings (CPXENVptr env, int setting)
{
   int status = 0;
   struct paramvalue const *vals = settings[setting % NUMSETTINGS].values;

   status = CPXXsetintparam (env, CPXPARAM_RandomSeed, setting);
   if ( status ) {
      fprintf (stderr, "CPXXsetintparam(CPXPARAM_RandomSeed): %d\n", status);
      abort ();
   }

   while (vals->type != CPX_PARAMTYPE_NONE) {
      switch (vals->type) {
      case CPX_PARAMTYPE_INT:
         status = CPXXsetintparam (env, vals->num, vals->value.i);
         break;
      case CPX_PARAMTYPE_LONG:
         status = CPXXsetlongparam (env, vals->num, vals->value.l);
         break;
      case CPX_PARAMTYPE_DOUBLE:
         status = CPXXsetdblparam (env, vals->num, vals->value.d);
         break;
      }
      if ( status ) {
         fprintf (stderr, "CPXXset???param(%d): %d\n", vals->num, status);
         abort ();
      }
      ++vals;
   }
}
예제 #2
0
int
main (void)
{
   int status;
   CPXENVptr env;
   CPXLPptr lp;
   CPXDIM i;
   double x[NUMCOLS];
   double cpi[NUMCOLS];
   double rpi[NUMROWS];
   double qpi[NUMQS];
   double slack[NUMROWS], qslack[NUMQS];
   double kktsum[NUMCOLS];

   /* ********************************************************************** *
    *                                                                        *
    *    S E T U P   P R O B L E M                                           *
    *                                                                        *
    * ********************************************************************** */

   /* Create CPLEX environment and enable screen output.
    */
   env = CPXXopenCPLEX (&status);
   if ( status != 0 )
      goto TERMINATE;
   status = CPXXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status != 0 )
      goto TERMINATE;

   /* Create the problem object and populate it.
    */
   lp = CPXXcreateprob (env, &status, "qcpdual");
   if ( status != 0 )
      goto TERMINATE;
   status = CPXXnewcols (env, lp, NUMCOLS, obj, lb, ub, NULL, cname);
   if ( status != 0 )
      goto TERMINATE;
   status = CPXXaddrows (env, lp, 0, NUMROWS, NUMNZS, rhs, sense,
                         rmatbeg, rmatind, rmatval, NULL, rname);
   if ( status != 0 )
      goto TERMINATE;
   for (i = 0; i < NUMQS; ++i) {
      CPXNNZ const linend = (i == NUMQS - 1) ? NUMLINNZ : linbeg[i + 1];
      CPXNNZ const quadend = (i == NUMQS - 1) ? NUMQUADNZ : quadbeg[i + 1];

      status = CPXXaddqconstr (env, lp, linend - linbeg[i],
                               quadend - quadbeg[i], qrhs[i], qsense[i],
                               &linind[linbeg[i]], &linval[linbeg[i]],
                               &quadrow[quadbeg[i]], &quadcol[quadbeg[i]],
                               &quadval[quadbeg[i]], qname[i]);
      if ( status != 0 )
         goto TERMINATE;
   }

   /* ********************************************************************** *
    *                                                                        *
    *    O P T I M I Z E   P R O B L E M                                     *
    *                                                                        *
    * ********************************************************************** */
   status = CPXXsetdblparam (env, CPXPARAM_Barrier_QCPConvergeTol, 1e-10);
   if ( status != 0 )
      goto TERMINATE;

   /* Solve the problem.
    */
   status = CPXXbaropt (env, lp);
   if ( status != 0 )
      goto TERMINATE;

   if ( CPXXgetstat (env, lp) != CPX_STAT_OPTIMAL ) {
      fprintf (stderr, "No optimal solution found!\n");
      goto TERMINATE;
   }

   /* ********************************************************************** *
    *                                                                        *
    *    Q U E R Y   S O L U T I O N                                         *
    *                                                                        *
    * ********************************************************************** */

   /* Optimal solution and slacks for linear and quadratic constraints. */
   status = CPXXgetx (env, lp, x, 0, NUMCOLS - 1);
   if ( status != 0 )
      goto TERMINATE;
   status = CPXXgetslack (env, lp, slack, 0, NUMROWS - 1);
   if ( status != 0 )
      goto TERMINATE;
   status = CPXXgetqconstrslack (env, lp, qslack, 0, NUMQS - 1);
   if ( status != 0 )
      goto TERMINATE;
   /* Dual multipliers for linear constraints and bound constraints. */
   status = CPXXgetdj (env, lp, cpi, 0, NUMCOLS - 1);
   if ( status != 0 )
      goto TERMINATE;
   status = CPXXgetpi (env, lp, rpi, 0, NUMROWS - 1);
   if ( status != 0 )
      goto TERMINATE;
   status = getqconstrmultipliers (env, lp, x, qpi, ZEROTOL);
   if ( status != 0 )
      goto TERMINATE;

   /* ********************************************************************** *
    *                                                                        *
    *    C H E C K   K K T   C O N D I T I O N S                             *
    *                                                                        *
    *    Here we verify that the optimal solution computed by CPLEX (and     *
    *    the qpi[] values computed above) satisfy the KKT conditions.        *
    *                                                                        *
    * ********************************************************************** */

   /* Primal feasibility: This example is about duals so we skip this test. */

   /* Dual feasibility: We must verify
    * - for <= constraints (linear or quadratic) the dual
    *   multiplier is non-positive.
    * - for >= constraints (linear or quadratic) the dual
    *   multiplier is non-negative.
    */
   for (i = 0; i < NUMROWS; ++i) {
      switch (sense[i]) {
      case 'E': /* nothing */ break;
      case 'R': /* nothing */ break;
      case 'L':
         if ( rpi[i] > ZEROTOL ) {
            fprintf (stderr,
                     "Dual feasibility test failed for <= row %d: %f\n",
                     i, rpi[i]);
            status = -1;
            goto TERMINATE;
         }
         break;
      case 'G':
         if ( rpi[i] < -ZEROTOL ) {
            fprintf (stderr,
                     "Dual feasibility test failed for >= row %d: %f\n",
                     i, rpi[i]);
            status = -1;
            goto TERMINATE;
         }
         break;
      }
   }
   for (i = 0; i < NUMQS; ++i) {
      switch (qsense[i]) {
      case 'E': /* nothing */ break;
      case 'L':
         if ( qpi[i] > ZEROTOL ) {
            fprintf (stderr,
                     "Dual feasibility test failed for <= quad %d: %f\n",
                     i, qpi[i]);
            status = -1;
            goto TERMINATE;
         }
         break;
      case 'G':
         if ( qpi[i] < -ZEROTOL ) {
            fprintf (stderr,
                     "Dual feasibility test failed for >= quad %d: %f\n",
                     i, qpi[i]);
            status = -1;
            goto TERMINATE;
         }
         break;
      }
   }

   /* Complementary slackness.
    * For any constraint the product of primal slack and dual multiplier
    * must be 0.
    */
   for (i = 0; i < NUMROWS; ++i) {
      if ( sense[i] != 'E' && fabs (slack[i] * rpi[i]) > ZEROTOL ) {
         fprintf (stderr,
                  "Complementary slackness test failed for row %d: %f\n",
                  i, fabs (slack[i] * rpi[i]));
         status = -1;
         goto TERMINATE;
      }
   }
   for (i = 0; i < NUMQS; ++i) {
      if ( qsense[i] != 'E' && fabs (qslack[i] * qpi[i]) > ZEROTOL ) {
         fprintf (stderr,
                  "Complementary slackness test failed for quad %d: %f\n",
                  i, fabs (qslack[i] * qpi[i]));
         status = -1;
         goto TERMINATE;
      }
   }
   for (i = 0; i < NUMCOLS; ++i) {
      if ( ub[i] < CPX_INFBOUND ) {
         double const slk = ub[i] - x[i];
         double const dual = cpi[i] < -ZEROTOL ? cpi[i] : 0.0;
         if ( fabs (slk * dual) > ZEROTOL ) {
            fprintf (stderr,
                     "Complementary slackness test failed for ub %d: %f\n",
                     i, fabs (slk * dual));
            status = -1;
            goto TERMINATE;
         }
      }
      if ( lb[i] > -CPX_INFBOUND ) {
         double const slk = x[i] - lb[i];
         double const dual = cpi[i] > ZEROTOL ? cpi[i] : 0.0;
         if ( fabs (slk * dual) > ZEROTOL ) {
            printf ("lb=%f, x=%f, cpi=%f\n", lb[i], x[i], cpi[i]);
            fprintf (stderr,
                     "Complementary slackness test failed for lb %d: %f\n",
                     i, fabs (slk * dual));
            status = -1;
            goto TERMINATE;
         }
      }
   }

   /* Stationarity.
    * The difference between objective function and gradient at optimal
    * solution multiplied by dual multipliers must be 0, i.e., for the
    * optimal solution x
    * 0 == c
    *      - sum(r in rows)  r'(x)*rpi[r]
    *      - sum(q in quads) q'(x)*qpi[q]
    *      - sum(c in cols)  b'(x)*cpi[c]
    * where r' and q' are the derivatives of a row or quadratic constraint,
    * x is the optimal solution and rpi[r] and qpi[q] are the dual
    * multipliers for row r and quadratic constraint q.
    * b' is the derivative of a bound constraint and cpi[c] the dual bound
    * multiplier for column c.
    */

   /* Objective function. */
   for (i = 0; i < NUMCOLS; ++i)
      kktsum[i] = obj[i];

   /* Linear constraints.
    * The derivative of a linear constraint ax - b (<)= 0 is just a.
    */
   for (i = 0; i < NUMROWS; ++i) {
      CPXNNZ const end = (i == NUMROWS - 1) ? NUMNZS : rmatbeg[i + 1];
      CPXNNZ k;

      for (k = rmatbeg[i]; k < end; ++k)
         kktsum[rmatind[k]] -= rpi[i] * rmatval[k];
   }

   /* Quadratic constraints.
    * The derivative of a constraint xQx + ax - b <= 0 is
    * Qx + Q'x + a.
    */
   for (i = 0; i < NUMQS; ++i) {
      CPXDIM j;
      CPXNNZ k;

      for (j = linbeg[i]; j < linbeg[i] + linnzcnt[i]; ++j)
         kktsum[linind[j]] -= qpi[i] * linval[j];
      for (k = quadbeg[i]; k < quadbeg[i] + quadnzcnt[i]; ++k) {
         kktsum[quadrow[k]] -= qpi[i] * x[quadcol[k]] * quadval[k];
         kktsum[quadcol[k]] -= qpi[i] * x[quadrow[k]] * quadval[k];
      }
   }

   /* Bounds.
    * The derivative for lower bounds is -1 and that for upper bounds
    * is 1.
    * CPLEX already returns dj with the appropriate sign so there is
    * no need to distinguish between different bound types here.
    */
   for (i = 0; i < NUMCOLS; ++i) {
      kktsum[i] -= cpi[i];
   }

   for (i = 0; i < NUMCOLS; ++i) {
      if ( fabs (kktsum[i]) > ZEROTOL ) {
         fprintf (stderr, "Stationarity test failed at index %d: %f\n",
                  i, kktsum[i]);
         status = -1;
         goto TERMINATE;
      }
   }

   /* KKT conditions satisfied. Dump out the optimal solutions and
    * the dual values.
    */
   printf ("Optimal solution satisfies KKT conditions.\n");
   printf ("  x[] =");
   for (i = 0; i < NUMCOLS; ++i)
      printf (" %7.3f", x[i]);
   printf ("\n");
   printf ("cpi[] =");
   for (i = 0; i < NUMCOLS; ++i)
      printf (" %7.3f", cpi[i]);
   printf ("\n");
   printf ("rpi[] =");
   for (i = 0; i < NUMROWS; ++i)
      printf (" %7.3f", rpi[i]);
   printf ("\n");
   printf ("qpi[] =");
   for (i = 0; i < NUMQS; ++i)
      printf (" %7.3f", qpi[i]);
   printf ("\n");
   
 TERMINATE:
   /* ********************************************************************** *
    *                                                                        *
    *    C L E A N U P                                                       *
    *                                                                        *
    * ********************************************************************** */

   status = CPXXfreeprob (env, &lp);
   if ( status != 0 ) {
      fprintf (stderr, "WARNING: Failed to free problem: %d\n", status);
   }
   status = CPXXcloseCPLEX (&env);
   if ( status != 0 ) {
      fprintf (stderr, "WARNING: Failed to close CPLEX: %d\n", status);
   }

   return status;
}
예제 #3
0
int
main (int  argc,
      char *argv[])
{
   int status = 0;

   /* Declare and allocate space for the variables and arrays where
      we will store the optimization results, including the status, 
      objective value, and variable values */
   
   int    solstat;
   double objval;
   double *x = NULL;
   
   CPXENVptr env = NULL;
   CPXLPptr  lp = NULL;

   CPXDIM j;
   CPXDIM cur_numcols;
   int wantorig = 1;
   int nameind = 1;

   /* Check the command line arguments */

   if ( argc != 2 ) {
      if ( argc != 3         ||
           argv[1][0] != '-' ||
           argv[1][1] != 'r'   ) {
         usage (argv[0]);
         goto TERMINATE;
      }
      wantorig = 0;
      nameind = 2;
   }

   /* Initialize the CPLEX environment */

   env = CPXXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  A call to CPXXgeterrorstring will produce the text of
      the error message.  Note that CPXXopenCPLEX produces no
      output, so the only way to see the cause of the error is to use
      CPXXgeterrorstring.  For other CPLEX routines, the errors will
      be seen if the CPXPARAM_ScreenOutput parameter is set to CPX_ON */

   if ( env == NULL ) {
      char errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment.\n");
      CPXXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto TERMINATE;
   }

   /* Turn on output to the screen */

   status = CPXXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status != 0 ) {
      fprintf (stderr, 
               "Failure to turn on screen indicator, error %d.\n",
               status);
      goto TERMINATE;
   }

   /* Create the problem, using the filename as the problem name */

   lp = CPXXcreateprob (env, &status, argv[nameind]);

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of
      failure, an error message will have been written to the error
      channel from inside CPLEX.  In this example, the setting of
      the parameter CPXPARAM_ScreenOutput causes the error message to
      appear on stdout.  Note that most CPLEX routines return
      an error code to indicate the reason for failure */

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now read the file, and copy the data into the created lp */

   status = CPXXreadcopyprob (env, lp, argv[nameind], NULL);
   if ( status ) {
      fprintf (stderr,
               "Failed to read and copy the problem data.\n");
      goto TERMINATE;
   }

   if ( CPXXgetnumcols (env, lp) != CPXXgetnumbin (env, lp) ) {
      fprintf (stderr, "Problem contains non-binary variables, exiting\n");
      goto TERMINATE;
   }

   /* Set parameters */

   if ( wantorig ) {
      /* Assure linear mappings between the presolved and original
         models */

      status = CPXXsetintparam (env, CPXPARAM_Preprocessing_Linear, 0);
      if ( status )  goto TERMINATE;

      /* Let MIP callbacks work on the original model */

      status = CPXXsetintparam (env, CPXPARAM_MIP_Strategy_CallbackReducedLP,
                                CPX_OFF);
      if ( status )  goto TERMINATE;
   }

   

   status = CPXXsetdblparam (env, CPXPARAM_MIP_Tolerances_MIPGap,
                             (double) 1e-6);
   if ( status )  goto TERMINATE;

   /* Turn on traditional search for use with control callbacks */

   status = CPXXsetintparam (env, CPXPARAM_MIP_Strategy_Search,
                             CPX_MIPSEARCH_TRADITIONAL);
   if ( status )  goto TERMINATE;

   /* Set up to use MIP callback */

   status = CPXXsetheuristiccallbackfunc (env, rounddownheur, NULL);
   if ( status )  goto TERMINATE;

   /* Optimize the problem and obtain solution */

   status = CPXXmipopt (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to optimize MIP.\n");
      goto TERMINATE;
   }

   solstat = CPXXgetstat (env, lp);
   printf ("Solution status %d.\n", solstat);

   status = CPXXgetobjval (env, lp, &objval);
   if ( status ) {
      fprintf (stderr, "Failed to obtain objective value.\n");
      goto TERMINATE;
   }

   printf ("Objective value %.10g\n", objval);

   cur_numcols = CPXXgetnumcols (env, lp);

   /* Allocate space for solution */

   x = malloc (cur_numcols * sizeof (*x));
   if ( x == NULL ) {
      fprintf (stderr, "No memory for solution values.\n");
      goto TERMINATE;
   }

   status = CPXXgetx (env, lp, x, 0, cur_numcols-1);
   if ( status ) {
      fprintf (stderr, "Failed to obtain solution.\n");
      goto TERMINATE;
   }

   /* Write out the solution */

   for (j = 0; j < cur_numcols; j++) {
      if ( fabs (x[j]) > 1e-10 ) {
         printf ( "Column %d:  Value = %17.10g\n", j, x[j]);
      }
   }


TERMINATE:

   /* Free the solution vector */

   free_and_null ((char **) &x);

   /* Free the problem as allocated by CPXXcreateprob and
      CPXXreadcopyprob, if necessary */

   if ( lp != NULL ) {
      status = CPXXfreeprob (env, &lp);
      if ( status ) {
         fprintf (stderr, "CPXXfreeprob failed, error code %d.\n",
                  status);
      }
   }

   /* Free the CPLEX environment, if necessary */

   if ( env != NULL ) {
      status = CPXXcloseCPLEX (&env);

      /* Note that CPXXcloseCPLEX produces no output, so the only 
         way to see the cause of the error is to use
         CPXXgeterrorstring.  For other CPLEX routines, the errors 
         will be seen if the CPXPARAM_ScreenOutput parameter is set to 
         CPX_ON */

      if ( status ) {
         char errmsg[CPXMESSAGEBUFSIZE];
         fprintf (stderr, "Could not close CPLEX environment.\n");
         CPXXgeterrorstring (env, status, errmsg);
         fprintf (stderr, "%s", errmsg);
      }
   }
     
   return (status);

} /* END main */
int
main (int argc, char *argv[])
{
   /* Declare and allocate space for the variables and arrays where we will
      store the optimization results including the status, objective value,
      and variable values. */


   int      solstat;
   double   objval;
   double   incobjval;
   double   meanobjval;
   double   *x     = NULL;
   double   *incx  = NULL;
   int      numsol;
   int      numsolreplaced;
   int      numdiff;

   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           status;
   int           i;
   CPXDIM        j;
   CPXDIM        cur_numcols;

   /* Check the command line arguments */

   if ( argc != 2 ) {
      usage (argv[0]);
      goto TERMINATE;
   }

   /* Initialize the CPLEX environment */

   env = CPXXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  A call to CPXXgeterrorstring will produce the text of
      the error message.  Note that CPXXopenCPLEX produces no output,
      so the only way to see the cause of the error is to use
      CPXXgeterrorstring.  For other CPLEX routines, the errors will
      be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON.  */

   if ( env == NULL ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment.\n");
      CPXXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto TERMINATE;
   }

   /* Turn on output to the screen */

   status = CPXXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn on screen indicator, error %d.\n", status);
      goto TERMINATE;
   }

   /* Create the problem, using the filename as the problem name */

   lp = CPXXcreateprob (env, &status, argv[1]);

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of 
      failure, an error message will have been written to the error 
      channel from inside CPLEX.  In this example, the setting of
      the parameter CPXPARAM_ScreenOutput causes the error message to
      appear on stdout.  Note that most CPLEX routines return
      an error code to indicate the reason for failure.   */

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now read the file, and copy the data into the created lp */

   status = CPXXreadcopyprob (env, lp, argv[1], NULL);
   if ( status ) {
      fprintf (stderr, "Failed to read and copy the problem data.\n");
      goto TERMINATE;
   }

   /* Set the solution pool relative gap parameter to obtain solutions
      of objective value within 10% of the optimal */

   status = CPXXsetdblparam (env, CPXPARAM_MIP_Pool_RelGap, 0.1);
   if ( status ) {
      fprintf (stderr, 
               "Failed to set the solution pool relative gap, error %d.\n", 
               status);
      goto TERMINATE;
   }


   /* Optimize the problem and obtain multiple solutions. */

   status = CPXXpopulate (env, lp);

   if ( status ) {
      fprintf (stderr, "Failed to populate MIP.\n");
      goto TERMINATE;
   }

   solstat = CPXXgetstat (env, lp);
   printf ("Solution status: %d.\n", solstat);

   status  = CPXXgetobjval (env, lp, &incobjval);

   if ( status ) {
      fprintf (stderr,
               "Failed to obtain objective value for the incumbent.\n");
      goto TERMINATE;
   }

   printf ("Objective value of the incumbent: %.10g\n", incobjval);

   /* The size of the problem should be obtained by asking CPLEX what
      the actual size is. cur_numcols stores the current number 
      of columns. */

   cur_numcols = CPXXgetnumcols (env, lp);

   /* Allocate space for solution */

   incx = malloc (cur_numcols*sizeof(*incx));

   if ( incx == NULL ) {
      fprintf (stderr, "No memory for solution values for the incumbent.\n");
      goto TERMINATE;
   }

   status = CPXXgetx (env, lp, incx, 0, cur_numcols-1);
   if ( status ) {
      fprintf (stderr, "Failed to obtain the incumbent.\n");
      goto TERMINATE;
   }

   /* Write out the incumbent */

   for (j = 0; j < cur_numcols; j++) {
      printf ("Incumbent: Column %d:  Value = %17.10g\n", j, incx[j]);
   }
   printf ("\n");

   /* Get the number of solutions in the solution pool */

   numsol = CPXXgetsolnpoolnumsolns (env, lp);   
   printf ("The solution pool contains %d solutions.\n", numsol);

   /* Some solutions are deleted from the pool because of the solution
      pool relative gap parameter */

   numsolreplaced = CPXXgetsolnpoolnumreplaced (env, lp);
   printf (
"%d solutions were removed due to the solution pool relative gap parameter.\n",
          numsolreplaced);

   printf ("In total, %d solutions were generated.\n",
           numsol + numsolreplaced);
   
   /* Get the average objective value of solutions in the solution
      pool */

   status = CPXXgetsolnpoolmeanobjval (env, lp, &meanobjval);
   printf ("The average objective value of the solutions is %.10g.\n\n",
          meanobjval);

   /* Write out the objective value of each solution and its
      difference to the incumbent */

   x = malloc (cur_numcols*sizeof(*x));
   if ( x == NULL ) {
      fprintf (stderr, "No memory for solution values.\n");
      goto TERMINATE;
   }

   printf ("Solution        Objective   Number of variables\n");
   printf ("                value       that differ compared to\n");
   printf ("                            the incumbent\n");
  

   for (i = 0; i < numsol; i++) {
      char namei[BUFSIZE];
      CPXSIZE surplus;

      /* Write out objective value */

      CPXXgetsolnpoolsolnname (env, lp, namei, BUFSIZE, &surplus, i);
      printf ("%-15s ", namei); 


      status = CPXXgetsolnpoolobjval (env, lp, i, &objval);
      if ( status ) {
         fprintf (stderr,
                  "Failed to obtain objective value for solution %d.\n", i);
         goto TERMINATE;
      }
      printf ("%.10g         ", objval);

      status = CPXXgetsolnpoolx (env, lp, i, x, 0, cur_numcols-1);
      if ( status ) {
         fprintf (stderr, "Failed to obtain solution %d.\n", i);
         goto TERMINATE;
      }
      
      /* Compute the number of variables that differ in the solution
         and in the incumbent */

      numdiff = 0;
      for (j = 0; j < cur_numcols; j++) {
         if ( fabs (x[j] - incx[j]) > EPSZERO )
            numdiff++;
      }      
      printf ("%d / %d\n", numdiff, cur_numcols);
   }

   
TERMINATE:

   /* Free up the solution */

   free_and_null ((char **) &incx);
   free_and_null ((char **) &x);

   /* Free up the problem as allocated by CPXXcreateprob, if necessary */

   if ( lp != NULL ) {
      status = CPXXfreeprob (env, &lp);
      if ( status ) {
         fprintf (stderr, "CPXXfreeprob failed, error code %d.\n", status);
      }
   }

   /* Free up the CPLEX environment, if necessary */

   if ( env != NULL ) {
      status = CPXXcloseCPLEX (&env);

      /* Note that CPXXcloseCPLEX produces no output,
         so the only way to see the cause of the error is to use
         CPXXgeterrorstring.  For other CPLEX routines, the errors will
         be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */

      if ( status ) {
         char  errmsg[CPXMESSAGEBUFSIZE];
         fprintf (stderr, "Could not close CPLEX environment.\n");
         CPXXgeterrorstring (env, status, errmsg);
         fprintf (stderr, "%s", errmsg);
      }
   }
     
   return (status);

}  /* END main */
예제 #5
0
int
main (void)
{
   CPXENVptr env;
   CPXLPptr lp = NULL;
   CPXDIM *cone = NULL;
   int status;
   CPXCHANNELptr resc, warnc, errc, logc;
   int retval = -1;

   /* Initialize CPLEX and get a reference to the output channels.
    * If any of this fails immediately terminate the program.
    */
   env = CPXXopenCPLEX (&status);
   if ( env == NULL || status != 0 )
      abort ();

   status = CPXXgetchannels (env, &resc, &warnc, &errc, &logc);
   if ( status != 0 )
      abort ();

   /* CPLEX is fully setup. Enable output.
    */
   status = CPXXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status != 0 )
      goto TERMINATE;

   /* Create model. */
   lp = CPXXcreateprob (env, &status, "xsocpex1");
   if ( lp == NULL || status != 0 )
      goto TERMINATE;
   if ( !createmodel (env, lp, &cone) )
      goto TERMINATE;

   /* Solve the problem to optimality. */
   CPXXmsg (logc, "Optimizing ...\n");
   status = CPXXsetdblparam (env, CPXPARAM_Barrier_QCPConvergeTol, CONVTOL);
   if ( status != 0 )
      goto TERMINATE;
   if ( (status = CPXXhybbaropt (env, lp, CPX_ALG_NONE)) != 0 )
      goto TERMINATE;

   if ( CPXXgetstat (env, lp) != CPX_STAT_OPTIMAL ) {
      CPXXmsg (errc, "Cannot test KKT conditions on non-optimal solution.\n");
      goto TERMINATE;
   }

   /* Now test KKT conditions on the result. */
   if ( !checkkkt (env, lp, cone, TESTTOL) ) {
      CPXXmsg (logc, "Testing of KKT conditions failed.\n");
      CPXXmsg (errc, "Testing of KKT conditions failed.\n");
      goto TERMINATE;
   }

   CPXXmsg (resc, "KKT conditions are satisfied.\n");
   retval = 0;
 TERMINATE:
   free (cone);
   if ( lp != NULL )
      CPXXfreeprob (env, &lp);
   CPXXcloseCPLEX (&env);

   return retval;
}