Esempio n. 1
0
int
main (void)
{
   /* Declare pointers for the variables and arrays that will contain
      the data which define the LP problem.  The setproblemdata() routine
      allocates space for the problem data.  */

   char     *probname = NULL;
   CPXDIM   numcols;
   CPXDIM   numrows;
   int      objsen;
   double   *obj = NULL;
   double   *rhs = NULL;
   char     *sense = NULL;
   CPXNNZ   *matbeg = NULL;
   CPXDIM   *matcnt = NULL;
   CPXDIM   *matind = NULL;
   double   *matval = NULL;
   double   *lb = NULL;
   double   *ub = NULL;
   CPXNNZ   *qmatbeg = NULL;
   CPXDIM   *qmatcnt = NULL;
   CPXDIM   *qmatind = NULL;
   double   *qmatval = NULL;

   /* 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[NUMCOLS];
   double   pi[NUMROWS];
   double   slack[NUMROWS];
   double   dj[NUMCOLS];


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

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

   /* Fill in the data for the problem.  */

   status = setproblemdata (&probname, &numcols, &numrows, &objsen, &obj,
                            &rhs, &sense, &matbeg, &matcnt, &matind,
                            &matval, &lb, &ub, &qmatbeg, &qmatcnt,
                            &qmatind, &qmatval);
   if ( status ) {
      fprintf (stderr, "Failed to build problem data arrays.\n");
      goto TERMINATE;
   }

   /* Create the problem. */

   lp = CPXXcreateprob (env, &status, probname);

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

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

   /* Now copy the LP part of the problem data into the lp */

   status = CPXXcopylp (env, lp, numcols, numrows, objsen, obj, rhs,
                       sense, matbeg, matcnt, matind, matval,
                       lb, ub, NULL);

   if ( status ) {
      fprintf (stderr, "Failed to copy problem data.\n");
      goto TERMINATE;
   }

   status = CPXXcopyquad (env, lp, qmatbeg, qmatcnt, qmatind, qmatval);
   if ( status ) {
      fprintf (stderr, "Failed to copy quadratic matrix.\n");
      goto TERMINATE;
   }


   /* Optimize the problem and obtain solution. */

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

   status = CPXXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
   if ( status ) {
      fprintf (stderr, "Failed to obtain solution.\n");
      goto TERMINATE;
   }


   /* Write the output to the screen. */

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

   /* The size of the problem should be obtained by asking CPLEX what
      the actual size is, rather than using what was passed to CPXXcopylp.
      cur_numrows and cur_numcols store the current number of rows and
      columns, respectively.  */

   cur_numrows = CPXXgetnumrows (env, lp);
   cur_numcols = CPXXgetnumcols (env, lp);
   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 = CPXXwriteprob (env, lp, "qpex1.lp", NULL);
   if ( status ) {
      fprintf (stderr, "Failed to write LP to disk.\n");
      goto TERMINATE;
   }


TERMINATE:

   /* 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);
      }
   }

   /* Free up the problem data arrays, if necessary. */

   free_and_null ((char **) &probname);
   free_and_null ((char **) &obj);
   free_and_null ((char **) &rhs);
   free_and_null ((char **) &sense);
   free_and_null ((char **) &matbeg);
   free_and_null ((char **) &matcnt);
   free_and_null ((char **) &matind);
   free_and_null ((char **) &matval);
   free_and_null ((char **) &lb);
   free_and_null ((char **) &ub);
   free_and_null ((char **) &qmatbeg);
   free_and_null ((char **) &qmatcnt);
   free_and_null ((char **) &qmatind);
   free_and_null ((char **) &qmatval);

   return (status);

}  /* END main */
Esempio n. 2
0
int
main (void)
{
   /* Declare variables and arrays where we will store the
      optimization results including the status, objective value,
      and variable values. */

   int       solstat;
   double    objval;

   CPXDIM    colcnt = 0;
   double    *x = NULL;

   CPXENVptr env = NULL;
   CPXLPptr  lp = NULL;
   int       status;
   int       m, p;

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


   /* Formulate and solve the problem */

   lp = CPXXcreateprob (env, &status, "food manufacturing");

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

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

   /* Build the model */

   status = buildmodel (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to build model.\n");
      goto TERMINATE;
   }

   /* Write a copy of the problem to a file. */

   status = CPXXwriteprob (env, lp, "foodmanu.lp", NULL);
   if ( status ) {
      fprintf (stderr, "Failed to write LP to disk.\n");
      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);

   /* Write solution status, objective and solution vector to the screen. */

   printf ("\nSolution status = %d\n", solstat);

   status = CPXXgetobjval (env, lp, &objval);
   if ( status ) {
      fprintf (stderr,"No MIP objective value available.  Exiting...\n");
      goto TERMINATE;
   }

   printf ("Solution value (maximum profit) = %f\n\n", objval);

   colcnt = NUMVARS*NUMMONTHS*NUMPRODUCTS;
   x = malloc (colcnt * sizeof(*x));
   if ( x == NULL ) {
      status = CPXERR_NO_MEMORY;
      fprintf (stderr, "Could not allocate memory for solution.\n");
      goto TERMINATE;
   }

   status = CPXXgetx (env, lp, x, 0, colcnt - 1);
   if ( status ) {
      fprintf (stderr, "Failed to get optimal integer x.\n");
      goto TERMINATE;
   }

   for (m = 0; m < NUMMONTHS; m++) {
      printf ("Month %d \n", m);

      printf ("  . buy   ");
      for (p = 0; p < NUMPRODUCTS; p++)
         printf ("%f\t", x[varindex(m, p, BUY)]);
      printf ("\n");

      printf ("  . use   ");
      for (p = 0; p < NUMPRODUCTS; p++)
         printf ("%f\t", x[varindex (m, p, USE)]);
      printf ("\n");

      printf ("  . store ");
      for (p = 0; p < NUMPRODUCTS; p++)
         printf ("%f\t", x[varindex (m, p, STORE)]);
      printf ("\n");
   }

   /* Free problem */

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

 TERMINATE:

   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 */
int
main (void)
{
   /* Declare pointers for the variables and arrays that will contain
      the data which define the LP problem.  The setproblemdata() routine
      allocates space for the problem data.  */

   char     *probname = NULL;
   CPXDIM   numcols;
   CPXDIM   numrows;
   int      objsen;
   double   *obj = NULL;
   double   *rhs = NULL;
   char     *sense = NULL;
   CPXNNZ   *matbeg = NULL;
   CPXDIM   *matcnt = NULL;
   CPXDIM   *matind = NULL;
   double   *matval = NULL;
   double   *lb = NULL;
   double   *ub = NULL;
   CPXNNZ   *qmatbeg = NULL;
   CPXDIM   *qmatcnt = NULL;
   CPXDIM   *qmatind = NULL;
   double   *qmatval = NULL;

   /* Declare pointers for the variables that will contain the data
      for the constraint that cuts off certain local optima. */

   CPXDIM   numrows_extra;
   CPXNNZ   numnnz_extra;
   double   *rhs_extra = NULL;
   char     *sense_extra = NULL;
   CPXNNZ   *rmatbeg = NULL;
   CPXDIM   *rmatind = NULL;
   double   *rmatval = NULL;
   CPXDIM   rowind[1];

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

   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           status;

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

   /* Fill in the data for the problem.  */

   status = setproblemdata (&probname, &numcols, &numrows, &objsen, &obj,
                            &rhs, &sense, &matbeg, &matcnt, &matind,
                            &matval, &lb, &ub, &qmatbeg, &qmatcnt,
                            &qmatind, &qmatval,
                            &numrows_extra, &numnnz_extra, 
                            &rhs_extra, &sense_extra, 
                            &rmatbeg, &rmatind, &rmatval);
   if ( status ) {
      fprintf (stderr, "Failed to build problem data arrays.\n");
      goto TERMINATE;
   }

   /* Create the problem. */

   lp = CPXXcreateprob (env, &status, probname);

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

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

   /* Now copy the LP part of the problem data into the lp */

   status = CPXXcopylp (env, lp, numcols, numrows, objsen, obj, rhs,
                       sense, matbeg, matcnt, matind, matval,
                       lb, ub, NULL);

   if ( status ) {
      fprintf (stderr, "Failed to copy problem data.\n");
      goto TERMINATE;
   }

   status = CPXXcopyquad (env, lp, qmatbeg, qmatcnt, qmatind, qmatval);
   if ( status ) {
      fprintf (stderr, "Failed to copy quadratic matrix.\n");
      goto TERMINATE;
   }


   /* When a non-convex objective function is present, CPLEX will
      return error CPXERR_Q_NOT_POS_DEF unless the parameter
      CPXPARAM_SolutionTarget is set to accept first-order optimal
      solutions.  */
   status = CPXXsetintparam (env, CPXPARAM_SolutionTarget, CPX_SOLUTIONTARGET_FIRSTORDER);
   if ( status ) goto TERMINATE;

   /* Optimize the problem and obtain solution. */

   status = optimize_and_report(env, lp, &solstat, &objval);
   if ( status ) goto TERMINATE;


   /* Add a constraint to cut off the solution at (-1, 1) */

   status = CPXXaddrows (env, lp, 0, numrows_extra, numnnz_extra,
                        rhs_extra, sense_extra,
                        rmatbeg, rmatind, rmatval,
                        NULL, NULL);
   if ( status ) goto TERMINATE;

   status = optimize_and_report(env, lp, &solstat, &objval);
   if ( status ) goto TERMINATE;


   /* Reverse the sense of the new constraint to cut off the solution at (1, 1) */

   rowind[0] = CPXXgetnumrows (env, lp) - 1;
   status    = CPXXchgsense (env, lp, 1, rowind, "L");
   if ( status ) goto TERMINATE;

   status = optimize_and_report(env, lp, &solstat, &objval);
   if ( status ) goto TERMINATE;

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

   status = CPXXwriteprob (env, lp, "indefqpex1.lp", NULL);
   if ( status ) {
      fprintf (stderr, "Failed to write LP to disk.\n");
      goto TERMINATE;
   }


TERMINATE:

   /* 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);
      }
   }

   /* Free up the problem data arrays, if necessary. */

   free_and_null ((char **) &probname);
   free_and_null ((char **) &obj);
   free_and_null ((char **) &rhs);
   free_and_null ((char **) &sense);
   free_and_null ((char **) &matbeg);
   free_and_null ((char **) &matcnt);
   free_and_null ((char **) &matind);
   free_and_null ((char **) &matval);
   free_and_null ((char **) &lb);
   free_and_null ((char **) &ub);
   free_and_null ((char **) &qmatbeg);
   free_and_null ((char **) &qmatcnt);
   free_and_null ((char **) &qmatind);
   free_and_null ((char **) &qmatval);
   free_and_null ((char **) &rhs_extra);
   free_and_null ((char **) &sense_extra);
   free_and_null ((char **) &rmatbeg);
   free_and_null ((char **) &rmatind);
   free_and_null ((char **) &rmatval);

   return (status);

}  /* END main */
Esempio n. 4
0
int
main (void)
{
   char     probname[16];  /* Problem name is max 16 characters */

   /* 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[NUMCOLS];
   double   pi[NUMROWS];
   double   slack[NUMROWS];
   double   dj[NUMCOLS];


   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           status;
   CPXDIM        i, j;
   CPXDIM        cur_numrows, cur_numcols;
   char          errmsg[CPXMESSAGEBUFSIZE];

   CPXCHANNELptr  cpxerror   = NULL;
   CPXCHANNELptr  cpxwarning = NULL;
   CPXCHANNELptr  cpxresults = NULL;
   CPXCHANNELptr  ourchannel = NULL;

   char *errorlabel = "cpxerror";
   char *warnlabel  = "cpxwarning";
   char *reslabel   = "cpxresults";
   char *ourlabel   = "Our Channel";

   CPXFILEptr fpout  = NULL;


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

   /* Since the message handler is yet to be set up, we'll call our
      messaging function directly to print out any errors  */

   if ( env == NULL ) {
      ourmsgfunc ("Our Message", "Could not open CPLEX environment.\n");
      goto TERMINATE;
   }

   /* Now get the standard channels.  If an error, just call our
      message function directly. */

   status = CPXXgetchannels (env, &cpxresults, &cpxwarning, &cpxerror, NULL);
   if ( status ) {
      ourmsgfunc ("Our Message", "Could not get standard channels.\n");
      CPXXgeterrorstring (env, status, errmsg);
      ourmsgfunc ("Our Message", errmsg);
      goto TERMINATE;
   }

   /* Now set up the error channel first.  The label will be "cpxerror" */

   status = CPXXaddfuncdest (env, cpxerror, errorlabel, ourmsgfunc);
   if ( status ) {
      ourmsgfunc ("Our Message", "Could not set up error message handler.\n");
      CPXXgeterrorstring (env, status, errmsg);
      ourmsgfunc ("Our Message", errmsg);
   }

   /* Now that we have the error message handler set up, all CPLEX
      generated errors will go through ourmsgfunc.  So we don't have
      to use CPXXgeterrorstring to determine the text of the message.
      We can also use CPXXmsg to do any other printing.  */

   status = CPXXaddfuncdest (env, cpxwarning, warnlabel, ourmsgfunc);
   if ( status ) {
      CPXXmsg (cpxerror, "Failed to set up handler for cpxwarning.\n");
      goto TERMINATE;
   }

   status = CPXXaddfuncdest (env, cpxresults, reslabel, ourmsgfunc);
   if ( status ) {
      CPXXmsg (cpxerror, "Failed to set up handler for cpxresults.\n");
      goto TERMINATE;
   }
   
   /* Now turn on the iteration display. */

   status = CPXXsetintparam (env, CPXPARAM_Simplex_Display, 2);
   if ( status ) {
      CPXXmsg (cpxerror, "Failed to turn on simplex display level.\n");
      goto TERMINATE;
   }

   /* Create the problem. */

   strcpy (probname, "example");
   lp = CPXXcreateprob (env, &status, probname);

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

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

   /* Now populate the problem with the data. */

   status = populatebycolumn (env, lp);

   if ( status ) {
      CPXXmsg (cpxerror, "Failed to populate problem data.\n");
      goto TERMINATE;
   }


   /* Optimize the problem and obtain solution. */

   status = CPXXlpopt (env, lp);
   if ( status ) {
      CPXXmsg (cpxerror, "Failed to optimize LP.\n");
      goto TERMINATE;
   }

   status = CPXXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
   if ( status ) {
      CPXXmsg (cpxerror, "Failed to obtain solution.\n");
      goto TERMINATE;
   }


   /* Write the output to the screen.  We will also write it to a
      file as well by setting up a file destination and a function
      destination. */

   ourchannel = CPXXaddchannel (env);
   if ( ourchannel == NULL ) {
      CPXXmsg (cpxerror, "Failed to set up our private channel.\n");
      goto TERMINATE;
   }

   fpout = CPXXfopen ("lpex5.msg", "w");
   if ( fpout == NULL ) {
      CPXXmsg (cpxerror, "Failed to open lpex5.msg file for output.\n");
      goto TERMINATE;
   }
   status = CPXXaddfpdest (env, ourchannel, fpout);
   if ( status ) {
      CPXXmsg (cpxerror, "Failed to set up output file destination.\n");
      goto TERMINATE;
   }

   status = CPXXaddfuncdest (env, ourchannel, ourlabel, ourmsgfunc);
   if ( status ) {
      CPXXmsg (cpxerror, "Failed to set up our output function.\n");
      goto TERMINATE;
   }

   /* Now any message to channel ourchannel will go into the file 
      and into the file opened above. */

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

   /* The size of the problem should be obtained by asking CPLEX what
      the actual size is, rather than using sizes from when the problem
      was built.  cur_numrows and cur_numcols store the current number 
      of rows and columns, respectively.  */

   cur_numrows = CPXXgetnumrows (env, lp);
   cur_numcols = CPXXgetnumcols (env, lp);
   for (i = 0; i < cur_numrows; i++) {
      CPXXmsg (ourchannel, "Row %d:  Slack = %10f  Pi = %10f\n", 
              i, slack[i], pi[i]);
   }

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

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

   status = CPXXwriteprob (env, lp, "lpex5.lp", NULL);
   if ( status ) {
      CPXXmsg (cpxerror, "Failed to write LP to disk.\n");
      goto TERMINATE;
   }
   
   
TERMINATE:

   /* First check if ourchannel is open */

   if ( ourchannel != NULL ) {
      int  chanstat;
      chanstat = CPXXdelfuncdest (env, ourchannel, ourlabel, ourmsgfunc);
      if ( chanstat ) {
         strcpy (errmsg, "CPXXdelfuncdest failed.\n");
         ourmsgfunc ("Our Message", errmsg); 
         if (!status)  status = chanstat;
      }
      if ( fpout != NULL ) {
         chanstat = CPXXdelfpdest (env, ourchannel, fpout);
         if ( chanstat ) {
            strcpy (errmsg, "CPXXdelfpdest failed.\n");
            ourmsgfunc ("Our Message", errmsg);
            if (!status)  status = chanstat;
         }
         CPXXfclose (fpout);
      }

      chanstat = CPXXdelchannel (env, &ourchannel);
      if ( chanstat ) {
         strcpy (errmsg, "CPXXdelchannel failed.\n");
         ourmsgfunc ("Our Message", errmsg);
         if (!status)  status = chanstat;
      }
   }

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

   if ( lp != NULL ) {
      status = CPXXfreeprob (env, &lp);
      if ( status ) {
         strcpy (errmsg, "CPXXfreeprob failed.\n");
         ourmsgfunc ("Our Message", errmsg);
      }
   }

   /* Now delete our function destinations from the 3 CPLEX channels. */
   if ( cpxresults != NULL ) {
      int  chanstat;
      chanstat = CPXXdelfuncdest (env, cpxresults, reslabel, ourmsgfunc);
      if ( chanstat && !status ) {
         status = chanstat;
         strcpy (errmsg, "Failed to delete cpxresults function.\n");
         ourmsgfunc ("Our Message", errmsg);
      }
   }

   if ( cpxwarning != NULL ) {
      int  chanstat;
      chanstat = CPXXdelfuncdest (env, cpxwarning, warnlabel, ourmsgfunc);
      if ( chanstat && !status ) {
         status = chanstat;
         strcpy (errmsg, "Failed to delete cpxwarning function.\n");
         ourmsgfunc ("Our Message", errmsg);
      }
   }

   if ( cpxerror != NULL ) {
      int  chanstat;
      chanstat = CPXXdelfuncdest (env, cpxerror, errorlabel, ourmsgfunc);
      if ( chanstat && !status ) {
         status = chanstat;
         strcpy (errmsg, "Failed to delete cpxerror function.\n");
         ourmsgfunc ("Our Message", errmsg);
      }
   }

   /* 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 ) {
         strcpy (errmsg, "Could not close CPLEX environment.\n");
         ourmsgfunc ("Our Message", errmsg);
         CPXXgeterrorstring (env, status, errmsg);
         ourmsgfunc ("Our Message", errmsg);
      }
   }
     
   return (status);

}  /* END main */
Esempio n. 5
0
int
main (void)
{
   /* Declare variables and arrays where we will store the
      optimization results including the status, objective value,
      and variable values. */

   int      solstat;
   double   objval;
   double   x[2*NUMEDGES]; /* One flow variable and one fixed charge indicator
                              for each edge */

   CPXENVptr env = NULL;
   CPXLPptr  lp = NULL;
   int       status;
   int       j;


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

   lp = CPXXcreateprob (env, &status, "fixnet");

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

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

   /* Build the fixed-charge network flow model using
      indicator constraints. */

   status = buildnetwork (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to build network.\n");
      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);


   /* Write solution status and objective to the screen. */

   printf ("\nSolution status = %d\n", solstat);
 
   status = CPXXgetobjval (env, lp, &objval);
   if ( status ) {
      fprintf (stderr, "No MIP objective value available.  Exiting...\n");
      goto TERMINATE;
   }

   printf ("Solution value  = %f\n", objval);
   printf ("Solution vector:\n");
   dumpx (env, lp);

   status = CPXXgetx (env, lp, x, 0, 2*NUMEDGES-1);
   if ( status ) {
      fprintf (stderr, "Failed to get optimal integer x.\n");
      goto TERMINATE;
   }

   /* Make sure flow satisfies fixed-charge constraints */

   for (j = 0; j < NUMEDGES; j++) {
      if ( x[j] > 0.0001 && x[NUMEDGES+j] < 0.9999 ) {
         printf ("WARNING : Edge from %d to %d has non-zero flow %.3f\n",
                 orig[j], dest[j], x[j]);
         printf ("        : fixed-charge indicator has value %.6f.\n",
                 x[NUMEDGES+j]);
      }
   }
   printf("\n");

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

   status = CPXXwriteprob (env, lp, "fixnet.lp", NULL);
   if ( status ) {
      fprintf (stderr, "Failed to write LP to disk.\n");
      goto TERMINATE;
   }

   /* Free problem */

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

TERMINATE:

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