Пример #1
0
static int
populatebycolumn (CPXENVptr env, CPXLPptr lp)
{
   int        status    = 0;
   double     obj[NUMCOLS];
   double     lb[NUMCOLS];
   double     ub[NUMCOLS];
   char const *colname[NUMCOLS];
   CPXNNZ     matbeg[NUMCOLS];
   CPXDIM     matind[NUMNZ];
   double     matval[NUMNZ];
   double     rhs[NUMROWS];
   char       sense[NUMROWS];
   char const *rowname[NUMROWS];

   /* To build the problem by column, create the rows, and then 
      add the columns. */

   status = CPXXchgobjsen (env, lp, CPX_MAX);  /* Problem is maximization */
   if ( status )  goto TERMINATE;

   /* 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 = CPXXnewrows (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 = CPXXaddcols (env, lp, NUMCOLS, NUMNZ, obj, matbeg, matind,
                        matval, lb, ub, colname);
   if ( status )  goto TERMINATE;

TERMINATE:

   return (status);

}  /* END populatebycolumn */
Пример #2
0
static int
buildnetwork (CPXENVptr env, CPXLPptr lp)
{
   char       sense[NUMNODES];
   double     rhs[NUMNODES];
   CPXDIM     ind[2];
   double     val[2];
   char const *name[1];
   char        buffer[100];

   int      i, j;
   CPXDIM   varindex;
   CPXNNZ   zero = 0;
   double   dblzero = 0.0;
   double   dblone  = 1.0;
   char     binary = 'B';
   int      status = 0;

   /* Create constraint placeholders ---
        One constraint for each node (flow constraints)
   */

   for (i = 0; i < NUMNODES; i++) {
      rhs[i]   = demand[i];
      sense[i] = 'G';
   }
   status = CPXXnewrows (env, lp, NUMNODES, rhs, sense, NULL, NULL);
   if ( status ) {
      fprintf (stderr, "Could not create new rows.\n");
      goto TERMINATE;
   }

   /* Add flow variables */

   for (j = 0; j < NUMEDGES; j++) {
      ind[0] = orig[j];  /* Flow leaves origin */
      val[0] = -1.0;
      ind[1] = dest[j];  /* Flow arrives at destination */
      val[1] =  1.0;

      name[0] = buffer;
      sprintf(buffer, "x%d%d", orig[j], dest[j]);

      status = CPXXaddcols (env, lp, 1, 2, &unitcost[j], &zero, ind, val,
                            NULL, NULL, name);
      if ( status ) {
         fprintf (stderr, "Failed to add flow edge.\n");
         goto TERMINATE;
      }
   }

   /* Add fixed charge variables */
   for (j = 0; j < NUMEDGES; j++) {
      name[0] = buffer;
      sprintf(buffer, "f%d%d", orig[j], dest[j]);

      status = CPXXaddcols (env, lp, 1, 0, &fixedcost[j], &zero, ind, val,
                            &dblzero, &dblone, name);
      if ( status ) {
         fprintf (stderr, "Failed to add fixed charge variable.\n");
         goto TERMINATE;
      }

      varindex = NUMEDGES+j;
      status = CPXXchgctype (env, lp, 1, &varindex, &binary);
      if ( status ) {
         fprintf (stderr, "Failed to change variable type.\n");
         goto TERMINATE;
      }
      
   }

   /* Add indicator constraints --
        f = 0 -> x <= 0 */

   for (j = 0; j < NUMEDGES; j++) {
      varindex = j;
      sprintf(buffer, "indicator%d", j);

      status = CPXXaddindconstr (env, lp, NUMEDGES+j, 1, 1, 
                                0.0, 'L', &varindex, &dblone, buffer);
      if ( status ) {
         fprintf (stderr, "Failed to add indicator constraint.");
         goto TERMINATE;
      }
   }
   
TERMINATE:

   return (status);

}  /* END buildnetwork */
Пример #3
0
static int 
colsteel (int numprod, int tweeks, double const *rate,
          double const *inv0, double const *avail, double const *flatmarket,
          double const *prodcost, double const *invcost,
          double const *flatrevenue, CPXENVptr env, CPXLPptr lp)
{
   double *obj      = NULL;
   char   *sense    = NULL;
   CPXNNZ *cmatbeg  = NULL;
   CPXDIM *cmatind  = NULL;
   double *cmatval  = NULL;
   double *lb       = NULL;
   double *ub       = NULL;

   CPXCHANNELptr  cpxerror = NULL;

   int    t,p;      /* Various loop counters */
   CPXNNZ k;

   int  status = 0;

   printf ("Building model by column.\n");

   status = CPXXgetchannels (env, NULL, NULL, &cpxerror, NULL);
   if ( status )  goto TERMINATE;

   /* Set the objective sense to be maximize */

   status = CPXXchgobjsen (env, lp, CPX_MAX);
   if ( status ) {
      CPXXmsg (cpxerror, "Could not change objective sense. Error %d\n",
               status);
      goto TERMINATE;
   }

   /* Set up the constraints for the problem */

   /* First do the time constraints.  Allocate space for a sense array. */

   sense = malloc (tweeks*sizeof(*sense));
   if ( sense == NULL ) {
      status = -2;
      goto TERMINATE;
   }

   for (t = 0; t < tweeks; t++) {
      sense[t] = 'L';
   }

   status = CPXXnewrows (env, lp, tweeks, avail, sense, NULL, NULL);
   if ( status ) {
      CPXXmsg (cpxerror, 
              "CPXXnewrows failed to add time constraints.  Error %d\n",
              status);
      goto TERMINATE;
   }

   /* Free up the temporary sense array */
   free (sense);  sense = NULL;

   /* Now do the balance constraints.  
      Can do this without temporary arrays, because the only nonzero
      is the negative of the inventory levels.  */

   for (p = 0; p < numprod; p++) {
      double  temprhs = -inv0[p];

      /* Fill in the initial inventory level */
      status   = CPXXnewrows (env, lp, 1, &temprhs, NULL, NULL, NULL);
      if ( status ) {
         CPXXmsg (cpxerror, "%sfor product %d.  Error %d.\n", 
                 "CPXXnewrows failed to add initial inventory constraint\n",
                 p, status);
         goto TERMINATE;
      }

      /* The remaining balance constraints have 0.0 as the rhs value,
         and are equality constraints.  No need to specify the arrays */

      status   = CPXXnewrows (env, lp, tweeks-1, NULL, NULL, NULL, NULL);
      if ( status ) {
         CPXXmsg (cpxerror, "%sfor product %d.  Error %d.\n", 
                 "CPXXnewrows failed to add other inventory constraints\n",
                 p, status);
         goto TERMINATE;
      }

   }

   /* Now, add the variables.  For each set of variables, we allocate
    * arrays to hold the data for the CPXXaddcols() calls, and then free
    * them up, so that each set of variables is maintained in a "local"
    * piece of code.
    */

   /* First, do the Make variables.  Each Make[p][t] variable has
    * objective coefficient -prodcost[p], and bounds of (0, +infinity).
    * Each Make[p][t] variable appears in the constraints 
    * time(t) and balance(p,t).
    * Create temporary arrays to hold the objective coefficients,
    * lower and upper bounds, and matrix coefficients for one product.
    */

   obj     = malloc (tweeks*sizeof(*obj));
   cmatbeg = malloc (tweeks*sizeof(*cmatbeg));
   cmatind = malloc (2*tweeks*sizeof(*cmatind));
   cmatval = malloc (2*tweeks*sizeof(*cmatval));

   if ( obj     == NULL ||
        cmatbeg == NULL ||
        cmatind == NULL ||
        cmatval == NULL   ) {
      status = -2;
      goto TERMINATE;
   }

   for (p = 0; p < numprod; p++) {
      k = 0;     /* Reset the nonzero count for each product */
      for (t = 0; t < tweeks; t++) {
         cmatbeg[t] = k;
         obj[t]     = -prodcost[p];
         cmatind[k] = t;
         cmatval[k] = 1.0/rate[p];
         k++;
         cmatind[k] = (p + 1)*tweeks + t;
         cmatval[k] = 1.0;
         k++;
      }
      status = CPXXaddcols (env, lp, tweeks, k, obj, cmatbeg, cmatind,
                           cmatval, NULL, NULL, NULL);
      if ( status ) {
         CPXXmsg (cpxerror, "%sfor product %d.  Error %d.\n", 
                 "CPXXaddcols failed to add Make variables\n",
                 p, status);
         goto TERMINATE;
      }
   }

   /* Free up allocated memory used to add Make variables */

   free (obj);     obj = NULL;
   free (cmatbeg); cmatbeg = NULL;
   free (cmatind); cmatind = NULL;
   free (cmatval); cmatval = NULL;
   
   /* Now do the Inv variables in (p,t) order.  Each Inv[p][t] variable
    * has objective coefficient -invcost[p], and bounds of (0, +infinity).
    * If t is not tweeks-1, then Inv[p][t] appears in constraints
    *   balance(p,t) and balance(p,t+1).
    * If t is tweeks-1, then Inv[p][t] appears only in
    *   constraint balance(p,t).
    * Create temporary arrays to hold the objective coefficients,
    * lower and upper bounds, and matrix coefficients for one product.
    */

   obj     = malloc (tweeks*sizeof(*obj));
   cmatbeg = malloc (tweeks*sizeof(*cmatbeg));
   cmatind = malloc (2*tweeks*sizeof(*cmatind));
   cmatval = malloc (2*tweeks*sizeof(*cmatval));

   if ( obj     == NULL ||
        cmatbeg == NULL ||
        cmatind == NULL ||
        cmatval == NULL   ) {
      status = -2;
      goto TERMINATE;
   }

   for (p = 0; p < numprod; p++) {
      k = 0;   /* Reset the nonzero count for each product */
      for (t = 0; t < tweeks; t++) {
         obj[t]     = -invcost[p];
         cmatbeg[t] = k;
         cmatind[k] = (p+1)*tweeks + t;
         cmatval[k] = -1.0;
         k++;
         cmatind[k] = (p+1)*tweeks + t+1;
         cmatval[k] = 1.0;
         k++;
      }
      /* Now repair the coefficient for t=tweeks-1 by passing k-1 as
       * the number of nonzeros, so that the last coefficient is 
       * ignored. 
       */
      status = CPXXaddcols (env, lp, tweeks, k-1, obj, cmatbeg, cmatind,
                           cmatval, NULL, NULL, NULL);
      if ( status ) {
         CPXXmsg (cpxerror, "%sfor product %d.  Error %d.\n", 
                 "CPXXaddcols failed to add Inv variables\n",
                 p, status);
         goto TERMINATE;
      }
   }

   /* Free up allocated memory used to add Inv variables */

   free (obj);     obj = NULL;
   free (cmatbeg); cmatbeg = NULL;
   free (cmatind); cmatind = NULL;
   free (cmatval); cmatval = NULL;
   

   /* Now do the Sell[p][t] variables.  The objective coefficients of
    * Sell[p][t] is flatrevenue[p*tweeks+t], which means that
    * we can pull the objective coefficients from the slice of that
    * array.  The lower bounds are 0.0, and the upper bounds are
    * flatmarket[p*tweeks+t], which means that we can pull the
    * upper bounds from the slice of that array.  Each Sell variable
    * appears only in the balance(p,t) constraint. 
    * Create temporary arrays to hold the bounds, and matrix 
    * coefficients for one product.
    */

   cmatbeg = malloc (tweeks*sizeof(*cmatbeg));
   cmatind = malloc (tweeks*sizeof(*cmatind));
   cmatval = malloc (tweeks*sizeof(*cmatval));

   if ( cmatbeg == NULL ||
        cmatind == NULL ||
        cmatval == NULL   ) {
      status = -2;
      goto TERMINATE;
   }


   for (p = 0; p < numprod; p++) {
      k = 0;     /* Reset the nonzero count for each product */
      for (t = 0; t < tweeks; t++) {
         cmatbeg[t] = k;
         cmatind[k] = (p+1)*tweeks + t;
         cmatval[k] = -1.0;
         k++;
      }
      status = CPXXaddcols (env, lp, tweeks, k, &flatrevenue[p*tweeks], 
                           cmatbeg, cmatind, cmatval, NULL, 
                           &flatmarket[p*tweeks], NULL);
      if ( status ) {
         CPXXmsg (cpxerror, "%sfor product %d.  Error %d.\n", 
                 "CPXXaddcols failed to add Sell variables\n",
                 p, status);
         goto TERMINATE;
      }

   }

   /* Free up allocated memory used to add Sell variables */

   free (lb);      lb  = NULL;
   free (cmatbeg); cmatbeg = NULL;
   free (cmatind); cmatind = NULL;
   free (cmatval); cmatval = NULL;

TERMINATE:

   if ( obj     != NULL )   free ( obj );
   if ( sense   != NULL )   free ( sense );
   if ( cmatbeg != NULL )   free ( cmatbeg );
   if ( cmatind != NULL )   free ( cmatind );
   if ( cmatval != NULL )   free ( cmatval );
   if ( lb      != NULL )   free ( lb );
   if ( ub      != NULL )   free ( ub );

   return (status);

} /* END colsteel */