Beispiel #1
0
static int
populatebycolumn (CPXENVptr env, CPXLPptr lp)
{
   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];

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

   status = CPXchgobjsen (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 = 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);
   if ( status )  goto TERMINATE;

TERMINATE:

   return (status);

}  /* END populatebycolumn */
Beispiel #2
0
//*******************************************************************
CPXLPptr CSolver::LoadProblem(bool bMip) {


   m_lp = CPXcreateprob (m_env, &m_status, m_pszProbname);

   CPXchgobjsen (m_env, m_lp, m_nObjSense );

   if ( m_status != 0 ) {
        CPXgeterrorstring(m_env, m_status, m_error );
        return 0;
   }


   if ( m_status != 0 ) {
        CPXgeterrorstring(m_env, m_status, m_error );
        return 0;
   }

   m_status = CPXnewrows( m_env, m_lp, m_nRhsItems, m_pRhs,
                          m_pRhsSense, 0, m_rname);

   if ( m_status != 0 ) {
        CPXgeterrorstring(m_env, m_status, m_error );
        return 0;
   }

   if (!bMip)
     m_status = CPXnewcols( m_env, m_lp, m_nObjItems, m_pObj,
                            m_pBdl, m_pBdu, NULL, m_cname);
   else
     m_status = CPXnewcols( m_env, m_lp, m_nObjItems, m_pObj,
                            m_pBdl, m_pBdu, m_pCtype, m_cname);

   if ( m_status != 0 ) {
        CPXgeterrorstring(m_env, m_status, m_error );
        return 0;
   }

   m_status = CPXchgcoeflist(m_env, m_lp, m_nCoefItems,
                             m_pRowNdx, m_pColNdx, m_pCoef);
   if ( m_status != 0 ) {
        CPXgeterrorstring(m_env, m_status, m_error );
        return 0;
   }

   FreeMemory();

   return m_lp;

}
Beispiel #3
0
static int
populatebycolumn (CPXENVptr env, CPXLPptr lp,
                  int nfoods, double *cost, double *lb, double *ub, 
                  int nnutr, double *nutrmin, double *nutrmax,
                  double **nutrper)
{
   int status = 0;

   int i, j;

   int    zero    = 0;
   int    *ind    = NULL;
   double *val    = NULL;
   char   *sense  = NULL;
   double *rngval = NULL;

   sense = (char*)malloc(nnutr * sizeof(char));
   if ( sense == NULL ) {
      status = CPXERR_NO_MEMORY;
      goto TERMINATE;
   }
   for (i = 0; i < nnutr; i++) {
      sense[i] = 'R';
   }

   val = (double*)malloc(nnutr * sizeof(double));
   if ( val == NULL ) {
      status = CPXERR_NO_MEMORY;
      goto TERMINATE;
   }

   rngval = (double*)malloc(nnutr * sizeof(double));
   if ( rngval == NULL ) {
      status = CPXERR_NO_MEMORY;
      goto TERMINATE;
   }
   for (i = 0; i < nnutr; i++) {
      rngval[i] = nutrmax[i] - nutrmin[i];
   }

   ind = (int*) malloc(nfoods * sizeof(int));
   if ( ind == NULL ) {
      status = CPXERR_NO_MEMORY;
      goto TERMINATE;
   }
   for (i = 0; i < nnutr; i++) {
      ind[i] = i;
   }

   status = CPXnewrows (env, lp, nnutr, nutrmin, sense, rngval, NULL);
   if ( status )  goto TERMINATE;

   for (j = 0; j < nfoods; ++j) {
      for (i = 0; i < nnutr; i++) {
         val[i] = nutrper[i][j];
      }

      status = CPXaddcols (env, lp, 1, nnutr, cost+j, &zero,
                           ind, val, lb+j, ub+j, NULL);
      if ( status )  goto TERMINATE;
   }

TERMINATE:

   free_and_null ((char **)&sense);
   free_and_null ((char **)&rngval);
   free_and_null ((char **)&ind);
   free_and_null ((char **)&val);

   return (status);

}  /* END populatebycolumn */
inline int
populatebynonzero (CPXENVptr env, CPXLPptr lp, int m, int n, int timeout,
		sched_nodeinfo_t *node_array, solver_job_list_t *job_array)
{
	int NUMCOLS = n * (2 * m + 2);
	int NUMROWS = n * 3 + m * 2 + m * n * 2;
	int NUMNZ = 2 * n * (4 * m + 1); 
	int NZc = 0; /* nonzero counter */
	
	int status = 0;
	double *obj = NULL;
	obj = (double*)malloc(NUMCOLS * sizeof(double));
	double *lb = (double*)malloc(NUMCOLS * sizeof(double));
	double *ub = (double*)malloc(NUMCOLS * sizeof(double));
	double *rhs = (double*)malloc(NUMROWS * sizeof(double));
	char *sense = (char*)malloc(NUMROWS * sizeof(char));
	/*
	char **colname = (char**)malloc(NUMCOLS * sizeof(char*));
	char **rowname = (char**)malloc(NUMROWS * sizeof(char[10]));
	char str[10];
	*/
	int *rowlist = (int*)malloc(NUMNZ * sizeof(int));
	int *collist = (int*)malloc(NUMNZ * sizeof(int));
	double *vallist = (double*)malloc(NUMNZ * sizeof(double));
	int i, j, d;
	/*int rc = 0, cc = 0;*/

	CPXchgobjsen (env, lp, CPX_MAX);  /* Problem is maximization */

	/* row definitions */
	
	for (j = 0; j < n; j++) {
		sense[j] = 'E';
		rhs[j] = 0.0;
		/*debug3("cpueq row counter: %d, no: %d",rc++, j);*/
		/*sprintf(str,"CPUeq_%d",j+1);
		rowname[j] = str;*/
	}
	for (i = 0; i < m; i++) {
		sense[n + i] = 'L';
		rhs[n + i] = (double)(node_array[i].rem_cpus);
		/*sprintf(str,"NODEeq_%d",i+1);
		rowname[n + i] = str;*/
		/*debug3("nodeeq row counter: %d, no: %d",rc++, n+i);*/

		sense[n + m + i] = 'L';
		rhs[n + m + i] = (double)(node_array[i].rem_gpus);
		/*debug3("gpueq row counter: %d, no: %d",rc++, n+m+i);*/
		/*sprintf(str,"GPUeq_%d",i+1);
		rowname[n + m + i] = str;*/
	}

	for (j = 0; j < n; j++) {
		for (i = 0; i < m; i++) {
			d = n + 2 * m + j * m * 2 + i * 2;
			sense[d] = 'L';
			rhs[d] = 0.0;
			/*debug3("t_i_j_le row counter: %d, no: %d",rc++,d);*/
			/*sprintf(rowname[d],"t_%d_%d_LE",j+1,i+1);
			rowname[d] = str;*/
			sense[d + 1] = 'G';
			rhs[d + 1] = 0.0;
			/*debug3("t_i_j_ge row counter: %d, no: %d",rc++,d+1);*/
			/*sprintf(rowname[d+1],"t_%d_%d_GE",j+1,i+1);
			rowname[d+1] = str;*/
		}
	}

	for (j = 0; j < n; j++) {
		sense[n + 2 * m + n * m * 2 + j * 2] = 'L';
		rhs[n + 2 * m + n * m * 2 + j * 2] = 0.0;
		/*debug3("minmax row counter: %d, no: %d",rc++,n + 2 * m + n * m * 2 + j * 2);*/
		sense[n + 2 * m + n * m * 2 + j * 2 + 1] = 'G';
		rhs[n + 2 * m + n * m * 2 + j * 2 + 1] = 0.0;
		/*debug3("minmax row counter: %d, no: %d",rc++,n + 2 * m + n * m * 2 + j * 2 + 1);*/
		/*sprintf(str,"minmax_%d",j+1);
		rowname[n + 4 * m + n * m * 2 + j] = str;*/
	}

	status = CPXnewrows (env, lp, NUMROWS, rhs, sense, NULL, NULL);
	if ( status ) goto TERMINATE;

	/*debug3("ROWS: %d, column def starting",NUMROWS);*/
	/* column definitions */	
	for (j = 0; j < n; j++) {
		/*sprintf(str, "s_%d",j+1);
		colname[j] = str;*/
		lb[j] = 0.0;
		ub[j] = 1.0;
		/*debug3("s_j col counter: %d, no: %d",cc++,j);*/
	}

	/*debug3("defined s_j");*/
	for (i = 0; i < m; i++) {
		for (j = 0; j < n; j++) {
			/*sprintf(str, "x_%d_%d",i+1,j+1);
			colname[(i + 1) * n + j] = str;*/
			lb[(i + 1) * n + j] = 0.0;
			ub[(i + 1) * n + j] = CPX_INFBOUND;
			/*debug3("x_i_j col counter: %d, no: %d",cc++,(i+1)*n+j);*/
		}
	}
	/*debug3("defined x_i_j");*/

	for (j = 0; j < n; j++) {
		/*sprintf(str, "c_%d",j+1);
		colname[n * (m + 1) + j] = str;*/
		/* min_nodes_j <= c_j <= max_nodes_j */
		lb[n * (m + 1) + j] = (m + 1) * (job_array[j].min_nodes);
		ub[n * (m + 1) + j] = (m + 1) * (job_array[j].max_nodes);
		/*debug3("c_j col counter: %d, no: %d",cc++,n*(m+1)+j);*/
	}
	/*debug3("defined c_j");*/

	for (j = 0; j < n; j++) {
		for (i = 0; i < m; i++) {
			/*sprintf(str, "t_%d_%d",j+1,i+1);
			colname[n * (m + 2) + j * m + i] = str;*/
			lb[n * (m + 2) + j * m + i] = 0.0;
			ub[n * (m + 2) + j * m + i] = 1.0;
			/*debug3("t_i_j col counter: %d, no: %d",cc++,n*(m+2)+j*m+i);*/
		}
	}
	/*debug3("defined t_i_j");*/
	
	for (j = 0; j < NUMCOLS; j++) {
		obj[j] = 0;
	}
	for (j = 0; j < n; j++) {
		obj[j] = (job_array[j].priority);
		obj[n * (m + 1) + j] = (-1.0)*(job_array[j].priority);
	}

	status = CPXnewcols (env, lp, NUMCOLS, obj, lb, ub, NULL, NULL);
	if ( status )  goto TERMINATE;

	/*debug3("constraint coefficients");*/
	/* constraints */
	/* sum over nodes should be equal to job's required cpu */
	/* sum_i(x_ij) = r_j * s_j */
	for (j = 0; j < n; j++) {
		for (i = 0; i < m; i++) {
			rowlist[NZc] = j;			
			vallist[NZc] = 1.0;
			collist[NZc++] = (i + 1) * n + j;
			/*debug3("con1 collist %d",(i + 1) * n + j);*/
		}
		rowlist[NZc] = j;
		vallist[NZc] = (int)(-job_array[j].min_cpus);
		collist[NZc++] = j;
		/*debug3("con1 collist %d",j);*/
	}	
	/* nzc = m*n+n */

	/* sum over jobs for cpu should be available on nodes */
	/* sum_j(x_ij) <= R_i */
	for (i = 0; i < m; i++) {
		for (j = 0; j < n; j++) {
			/*debug3("con2 collist %d",(i + 1) * n + j);*/
			rowlist[NZc] = n + i;
			vallist[NZc] = 1.0;
			collist[NZc++] = (i + 1) * n + j;
		}
	}
	/* nzc = 2*m*n+n */

	/* sum over jobs for gpu should be available on nodes */
	/* sum_j(t_ji * g_j) <= G_i */
	for (i = 0; i < m; i++) {
		for (j = 0; j < n; j++) {
			rowlist[NZc] = n + m + i;
			vallist[NZc] = job_array[j].gpu;
			collist[NZc++] = n * (m + 2) + j * m + i;
			/*debug3("con3 collist %d",n * (m + 2) + j * m + i);*/
		}
	}
	/* nzc = 3*m*n+n */

	status = CPXchgcoeflist (env, lp, NZc, rowlist, collist, vallist);   
	if ( status )  goto TERMINATE;

TERMINATE:
	free_and_null ((char **) &obj);
	free_and_null ((char **) &lb);
	free_and_null ((char **) &ub);
	free_and_null ((char **) &rhs);
	free_and_null ((char **) &sense);
	return (status);
} 
static int
populatebynonzero (CPXENVptr env, CPXLPptr lp)
{
   int      status    = 0;
   double   obj[NUMCOLS];
   double   lb[NUMCOLS];
   double   ub[NUMCOLS];
   char     *colname[NUMCOLS];
   double   rhs[NUMROWS];
   char     sense[NUMROWS];
   char     *rowname[NUMROWS];
   int      rowlist[NUMNZ];
   int      collist[NUMNZ];
   double   vallist[NUMNZ];

   status = CPXchgobjsen (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 = 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;

        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 = CPXnewcols (env, lp, NUMCOLS, obj, lb, ub, NULL, colname);
   if ( status )  goto TERMINATE;

   /* Now create the list of coefficients */

   rowlist[0] = 0;   collist[0] = 0;   vallist[0] = -1.0;
   rowlist[1] = 0;   collist[1] = 1;   vallist[1] = 1.0;
   rowlist[2] = 0;   collist[2] = 2;   vallist[2] = 1.0;
   rowlist[3] = 1;   collist[3] = 0;   vallist[3] = 1.0;
   rowlist[4] = 1;   collist[4] = 1;   vallist[4] = -3.0;
   rowlist[5] = 1;   collist[5] = 2;   vallist[5] = 1.0;

   status = CPXchgcoeflist (env, lp, 6, rowlist, collist, vallist);
   
   if ( status )  goto TERMINATE;

TERMINATE:

   return (status);

}  /* END populatebynonzero */
Beispiel #6
0
static int
buildnetwork (CPXENVptr env, CPXLPptr lp)
{
   char     sense[NUMNODES];
   double   rhs[NUMNODES];
   int      ind[2];
   double   val[2];
   char     *name[1];
   char     buffer[100];

   int      i, j, varindex;
   int      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 = CPXnewrows (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 = CPXaddcols (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 = CPXaddcols (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 = CPXchgctype (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 = CPXaddindconstr (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 */
Beispiel #7
0
void
DDSIP_DetEqu ()
{
    CPXLPptr det_equ;

    int status, scen, i, j, k;
    char probname[] = "sipout/det_equ.lp.gz";
    double *obj_coef;
    double *scaled_obj_coef;
    char *sense;
    char **scen_spec_rowname;
    char **scen_spec_colname;
    char **rowname, *rownamestore;
    char **colname, *colnamestore;
    int rowstorespace, rowsurplus_p;
    int colstorespace, colsurplus_p;
    char *string1, *string2;
    double coef;
    double *lb, *lb_sorted;
    double *ub, *ub_sorted;
    char *vartype, *vartype_sorted;
    int *colindex_sorted, *colindex_revers, *matcol_sorted;
    double *value;
    double *det_equ_rhs = NULL;
    double *non_stoc_rhs = NULL;
    if (DDSIP_param->seccon)
        det_equ_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_param->seccon,"det_equ_rhs(DetEqu)");
    else
    {
        fprintf (stderr,"XXX ERROR: no second stage contraints, got DDSIP_param->seccon=%d.\n",DDSIP_param->seccon);
        exit (1);
    }
    if (DDSIP_param->seccon - DDSIP_param->stocrhs>0)
        non_stoc_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_param->seccon - DDSIP_param->stocrhs,"non_stoc_rhs(DetEqu)");

    fprintf (stderr,
             "\nBuilding deterministic equivalent. This may take some time.\nWorks only for expectation-based model so far.\n");

    if (!(sense = (char *) calloc (DDSIP_param->seccon, sizeof (char))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        return;
    }

    if (!(obj_coef = (double *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (double))) ||
            !(scaled_obj_coef = (double *) calloc (DDSIP_bb->secvar, sizeof (double))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        return;
    }


    det_equ = CPXcloneprob (DDSIP_env, DDSIP_lp, &status);
    CPXchgprobname (DDSIP_env, det_equ, probname);

    if (!(rowname = (char **) calloc (DDSIP_param->seccon, sizeof (char *)))
            || !(scen_spec_rowname = (char **) calloc (DDSIP_param->seccon, sizeof (char *)))
            || !(rownamestore = (char *) calloc (DDSIP_param->seccon * 255, sizeof (char))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        return;
    }
    rowstorespace = DDSIP_param->seccon * 255;
    status = CPXgetrowname (DDSIP_env, DDSIP_lp, rowname, rownamestore,
                            rowstorespace, &rowsurplus_p, DDSIP_param->firstcon, DDSIP_param->firstcon + DDSIP_param->seccon - 1);


    if (!(colname = (char **) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (char *)))
            || !(scen_spec_colname = (char **) calloc (DDSIP_param->secvar, sizeof (char *)))
            || !(colnamestore = (char *) calloc (DDSIP_param->secvar * 255, sizeof (char))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        return;
    }
    colstorespace = (DDSIP_param->firstvar + DDSIP_param->secvar) * 255;
    status = CPXgetcolname (DDSIP_env, DDSIP_lp, colname, colnamestore,
                            colstorespace, &colsurplus_p, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1);

    /*____________________________________________________________________________________*/
    status = CPXgetsense (DDSIP_env, DDSIP_lp, sense, DDSIP_param->firstcon, DDSIP_param->firstcon + DDSIP_param->seccon - 1);
    /*____________________________________________________________________________________*/
    status = CPXgetrhs (DDSIP_env, DDSIP_lp, non_stoc_rhs, DDSIP_param->firstcon + DDSIP_param->stocrhs, DDSIP_param->firstcon + DDSIP_param->seccon - 1);
    /*____________________________________________________________________________________*/
    status = CPXgetobj (DDSIP_env, DDSIP_lp, obj_coef, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1);
    /*____________________________________________________________________________________*/
    //copy rownames scenario many times, append scenario index
    //and enter sense and rhs
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        for (j = 0; j < DDSIP_param->seccon; j++)
        {
            if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
            {
                fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                return;
            }
            string1 = rowname[j];
            sprintf (string2, "%sSC%.3d", string1, scen);
            scen_spec_rowname[j] = string2;

            if (j < DDSIP_param->stocrhs)
                det_equ_rhs[j] = DDSIP_data->rhs[DDSIP_param->stocrhs * scen + j];
            else
                det_equ_rhs[j] = non_stoc_rhs[j - DDSIP_param->stocrhs];
        }
        status = CPXnewrows (DDSIP_env, det_equ, DDSIP_param->seccon, det_equ_rhs, sense, NULL, scen_spec_rowname);
        for (j = 0; j < DDSIP_param->seccon; j++)
            DDSIP_Free ((void **) &(scen_spec_rowname[j]));
    }

    //copy colnames scenario many times, append scenario index
    //and enter into constraint matrix
    if (!(lb = (double *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (double)))
            || !(lb_sorted = (double *) calloc (DDSIP_param->secvar, sizeof (double)))
            || !(ub = (double *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (double)))
            || !(ub_sorted = (double *) calloc (DDSIP_param->secvar, sizeof (double)))
            || !(vartype = (char *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (char)))
            || !(vartype_sorted = (char *) calloc (DDSIP_param->secvar, sizeof (double)))
            || !(colindex_revers = (int *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (int)))
            || !(colindex_sorted = (int *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (int))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        return;
    }

    status = CPXgetlb (DDSIP_env, det_equ, lb, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1);
    status = CPXgetub (DDSIP_env, det_equ, ub, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1);
    status = CPXgetctype (DDSIP_env, det_equ, vartype, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1);
    for (j = 0; j < DDSIP_param->secvar; j++)
    {
        vartype_sorted[j] = vartype[DDSIP_bb->secondindex[j]];
        lb_sorted[j] = lb[DDSIP_bb->secondindex[j]];
        ub_sorted[j] = ub[DDSIP_bb->secondindex[j]];
    }


    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        for (j = 0; j < DDSIP_param->secvar; j++)
        {
            if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
            {
                fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                return;
            }
            string1 = colname[DDSIP_bb->secondindex[j]];
            sprintf (string2, "%sSC%.3d", string1, scen);
            scen_spec_colname[j] = string2;
            scaled_obj_coef[j] = DDSIP_data->prob[scen] * obj_coef[DDSIP_bb->secondindex[j]];
        }

        status =
            CPXnewcols (DDSIP_env, det_equ, DDSIP_param->secvar, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname);
        for (j = 0; j < DDSIP_param->secvar; j++)
            DDSIP_Free ((void **) &(scen_spec_colname[j]));

    }

    /////////////////////////////////////////////////
    for (j = 0; j < DDSIP_param->firstvar; j++)
    {
        colindex_sorted[j] = DDSIP_bb->firstindex[j];
    }
    for (j = 0; j < DDSIP_param->secvar; j++)
    {
        colindex_sorted[DDSIP_param->firstvar + j] = DDSIP_bb->secondindex[j];
    }
    for (j = 0; j < DDSIP_param->firstvar + DDSIP_param->secvar; j++)
    {
        colindex_revers[colindex_sorted[j]] = j;
    }

    k = DDSIP_param->seccon / 60;
    printf ("\n0%%                                                         100%%\n");
    for (i = 0; i < DDSIP_param->seccon; i++)
    {
        for (j = 0; j < DDSIP_param->firstvar; j++)
        {
            if ((status = CPXgetcoef (DDSIP_env, det_equ, DDSIP_param->firstcon + i, colindex_sorted[j], &coef)))
            {
                fprintf (stderr, " Build det. equivalent: Error retrieving coefficient of first-stage Variable %d.\n", j);
                exit (1);
            }
            if (coef)
            {
                for (scen = 0; scen < DDSIP_param->scenarios; scen++)
                {
                    status =
                        CPXchgcoef (DDSIP_env, det_equ, DDSIP_param->firstcon + DDSIP_bb->seccon + scen * DDSIP_param->seccon + i, colindex_sorted[j], coef);
                    if (status)
                    {
                        fprintf (stderr, " Build det. equivalent: Error setting coefficient of first-stage Variable %d.\n", j);
                        exit (1);
                    }
                }
            }
        }
        for (j = DDSIP_param->firstvar; j < DDSIP_param->firstvar + DDSIP_param->secvar; j++)
        {
            if ((status = CPXgetcoef (DDSIP_env, det_equ, DDSIP_param->firstcon + i, colindex_sorted[j], &coef)))
            {
                fprintf (stderr,
                         " Build det. equivalent: Error retrieving coefficient of second-stage Variable %d.\n",
                         j - DDSIP_param->firstvar);
                exit (1);
            }
            if (coef)
            {
                for (scen = 0; scen < DDSIP_param->scenarios; scen++)
                {
                    status =
                        CPXchgcoef (DDSIP_env, det_equ,
                                    DDSIP_param->firstcon + DDSIP_bb->seccon + scen * DDSIP_param->seccon + i, (scen + 1) * DDSIP_param->secvar + j, coef);
                }
                if (status)
                {
                    fprintf (stderr,
                             " Build det. equivalent: Error setting coefficient of second-stage Variable %d.\n",
                             j - DDSIP_param->firstvar);
                    exit (1);
                }
            }
        }
        if (!k)
        {
            for (j = 0; j <= 60 / DDSIP_param->seccon; j++)
                printf ("#");
        }
        else if (i % k == k - 1)
            printf ("#");
    }
    printf ("\n\n");

    ///////delete original second stage rows & cols ////////////////////////////////////////////

    status = CPXdelrows (DDSIP_env, det_equ, DDSIP_param->firstcon, DDSIP_param->firstcon + DDSIP_bb->seccon - 1);
    j = 0;
    for (i = 0; i < DDSIP_param->secvar; i++)
    {
        status = CPXdelcols (DDSIP_env, det_equ, DDSIP_bb->secondindex[i] - j, DDSIP_bb->secondindex[i] - j);
        j++;
    }

    ///////enter stochastic matrix entries//////////////////////////////////////////////////////
    if (DDSIP_param->stocmat)
    {

        if (!(value = (double *) calloc (DDSIP_param->stocmat, sizeof (double)))
                || !(matcol_sorted = (int *) calloc (DDSIP_param->stocmat, sizeof (int))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            return;
        }
        for (j = 0; j < DDSIP_param->stocmat; j++)
        {
            matcol_sorted[j] = colindex_revers[DDSIP_data->matcol[j]];
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                value[j] = DDSIP_data->matval[scen * DDSIP_param->stocmat + j];
            }
            status = CPXchgcoeflist (DDSIP_env, det_equ, DDSIP_param->stocmat, DDSIP_data->matrow, matcol_sorted, value);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu: %s\n", errmsg);
            }
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                DDSIP_data->matrow[j] += DDSIP_param->seccon;
                if (matcol_sorted[j] >= DDSIP_param->firstvar)
                    matcol_sorted[j] += DDSIP_param->secvar;
            }
        }
        DDSIP_Free ((void **) &(value));
        DDSIP_Free ((void **) &(matcol_sorted));
        //set matrow to the old values
        for (j = 0; j < DDSIP_param->stocmat; j++)
        {
            DDSIP_data->matrow[j] -= DDSIP_param->scenarios * DDSIP_param->seccon;
        }

    }
    ///////enter stochastic cost coefficients //////////////////////////////////////////////////
    if (DDSIP_param->stoccost)
    {

        if (!(value = (double *) calloc (DDSIP_param->stoccost, sizeof (double)))
                || !(matcol_sorted = (int *) calloc (DDSIP_param->stoccost, sizeof (int))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            return;
        }
        for (j = 0; j < DDSIP_param->stoccost; j++)
        {
            value[j] = 0.0;
            matcol_sorted[j] = colindex_revers[DDSIP_data->costind[j]];
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if (matcol_sorted[j] >= DDSIP_param->firstvar)
                    value[j] = DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
                else
                    value[j] += DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
            }
            status = CPXchgobj (DDSIP_env, det_equ, DDSIP_param->stoccost, matcol_sorted, value);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu: %s\n", errmsg);
            }
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if (matcol_sorted[j] >= DDSIP_param->firstvar)
                    matcol_sorted[j] += DDSIP_param->secvar;
            }
        }
        DDSIP_Free ((void **) &(value));
        DDSIP_Free ((void **) &(matcol_sorted));

    }
    ////////////////////////////////////////////////////////////////////////////////////////////

    status = CPXwriteprob (DDSIP_env, det_equ, probname, NULL);
    if (status)
        fprintf (DDSIP_outfile, " *** Deterministic equivalent not written successfully, status = %d\n", status);
    else
        fprintf (DDSIP_outfile, " *** Deterministic equivalent written successfully\n");
    status = CPXfreeprob (DDSIP_env, &det_equ);

    DDSIP_Free ((void **) &(sense));
    DDSIP_Free ((void **) &(vartype));
    DDSIP_Free ((void **) &(rowname));
    DDSIP_Free ((void **) &(rownamestore));
    DDSIP_Free ((void **) &(colname));
    DDSIP_Free ((void **) &(colnamestore));
    DDSIP_Free ((void **) &(det_equ_rhs));
    DDSIP_Free ((void **) &(non_stoc_rhs));
    DDSIP_Free ((void **) &(lb));
    DDSIP_Free ((void **) &(ub));
    DDSIP_Free ((void **) &(vartype_sorted));
    DDSIP_Free ((void **) &(lb_sorted));
    DDSIP_Free ((void **) &(ub_sorted));
    DDSIP_Free ((void **) &(obj_coef));
    DDSIP_Free ((void **) &(scaled_obj_coef));
    DDSIP_Free ((void **) &(colindex_sorted));
    DDSIP_Free ((void **) &(colindex_revers));
    DDSIP_Free ((void **) &(scen_spec_rowname));
    DDSIP_Free ((void **) &(scen_spec_colname));
    return;
}
Beispiel #8
0
long GenModelCplex::CreateModel()
{
    if(!binit)
        return ThrowError("CreateModel() not available : Problem not initialized yet");
    CplexData* d = (CplexData*)solverdata;
    int status = 0;
    d->nc = nc;
    d->nc = nc;
    d->onc = nc;
    d->onr = nr;

    if(boolParam.count("maximize") > 0 && boolParam["maximize"])
        CPXchgobjsen (d->env, d->lp, CPX_MAX);
    else
        CPXchgobjsen (d->env, d->lp, CPX_MIN);
    d->lrhs = new double[nr];
    d->urhs = new double[nr];
    d->sense = new char[nr];
    d->ub = new double[nc];
    d->lb = new double[nc];
    d->obj = new double[nc];
    d->type = new char[nc];
    d->mat_r = new int[nz];
    d->mat_c = new int[nz];
    d->mat_v = new double[nz];
    d->cname = new char*[nc];
    d->rname = new char*[nr];


    nz=0;
    for(unsigned long i = 0; i < nr; i++)
    {
        d->rname[i] = new char[consts[i].name.length()+1];
        snprintf(d->rname[i], consts[i].name.length()+1, "%s", consts[i].name.c_str());
        //printf("%ld %s: ", i, consts[i].name.c_str());
        for(unsigned long j = 0; j < consts[i].nz; j++)
        {
            d->mat_r[nz] = i;
            d->mat_c[nz] = consts[i].cols[j];
            d->mat_v[nz] = consts[i].coefs[j];
            //if(i >= 198)
                //printf("(%ld,%ld(%s),%f) ", d->mat_r[nz], d->mat_c[nz], vars.name[d->mat_c[nz]].c_str(), d->mat_v[nz]);
            nz++;
        }

        if(consts[i].lrhs == numeric_limits<double>::infinity())
            d->lrhs[i] = CPX_INFBOUND;
        else if(consts[i].lrhs == -numeric_limits<double>::infinity())
            d->lrhs[i] = -CPX_INFBOUND;
        else
            d->lrhs[i] = consts[i].lrhs;
        if(consts[i].urhs == numeric_limits<double>::infinity())
            d->urhs[i] = CPX_INFBOUND;
        else if(consts[i].urhs == -numeric_limits<double>::infinity())
            d->urhs[i] = -CPX_INFBOUND;
        else
            d->urhs[i] = consts[i].urhs-consts[i].lrhs;
        d->sense[i] = consts[i].sense;
    //	printf("%ld/%ld -> %c\n", i, nr, d->sense[i]);
    }
    for(unsigned long i = 0; i < nc; i++)
    {
        d->cname[i] = new char[vars.name[i].length()+1];
        snprintf(d->cname[i], vars.name[i].length()+1, "%s", vars.name[i].c_str());
        d->obj[i] = vars.obj[i];
        if(vars.ub[i] == numeric_limits<double>::infinity())
            d->ub[i] = CPX_INFBOUND;
        else if(vars.ub[i] == -numeric_limits<double>::infinity())
            d->ub[i] = -CPX_INFBOUND;
        else
            d->ub[i] = vars.ub[i];
        if(vars.lb[i] == numeric_limits<double>::infinity())
            d->lb[i] = CPX_INFBOUND;
        else if(vars.lb[i] == -numeric_limits<double>::infinity())
            d->lb[i] = -CPX_INFBOUND;
        else
            d->lb[i] = vars.lb[i];
        d->type[i] = vars.type[i];

        //printf("%ld (%s) -> %f %f %f %c\n", i, vars.name[i].c_str(), d->obj[i], d->lb[i], d->ub[i], d->type[i]);
    }
    status = CPXnewrows (d->env, d->lp, nr, d->lrhs, d->sense, d->urhs, d->rname);
    if ( status )
    {
        char  errmsg[1024];
        fprintf (stderr, "Could not create new rows.\n");
        CPXgeterrorstring (d->env, status, errmsg);
        fprintf (stderr, "%s", errmsg);
        return 1;
    }
    //else
        //printf("Row added!\n");

    if(boolParam.count("mip") > 0 && boolParam["mip"])
        status = CPXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, d->type, d->cname);
    else
        status = CPXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, NULL, NULL);
    if ( status )
    {
        char  errmsg[1024];
        fprintf (stderr, "Could not create new cols.\n");
        CPXgeterrorstring (d->env, status, errmsg);
        fprintf (stderr, "%s", errmsg);
        return 1;
    }
    //status = CPXnewcols (env, lp, nc, obj, lb, ub, NULL, colname);
    if ( status )
        return 1;
    //else
        //printf("Col added!\n");
    status = CPXchgcoeflist (d->env, d->lp, nz, d->mat_r, d->mat_c, d->mat_v);
    if ( status )
        return 1;

    vector<long>::iterator iti;
    vector<long>::iterator itj = vars.qj.begin();
    vector<double>::iterator itv = vars.qobj.begin();

    vector<vector<pair<int,double> > > qptemp;
    qptemp.resize(nc);
    int* qpbeg = NULL;
    int* qpnum = NULL;
    int* qpind = NULL;
    double* qpv = NULL;
    int qpnz = 0;

    if(!vars.qi.empty())
    {
        boolParam["qp"] = true;
        qpbeg = new int[nc];
        qpnum = new int[nc];
    }
    if(boolParam.count("qp_mat") == 0 || boolParam["qp_mat"])
    {
        for(iti = vars.qi.begin(); iti != vars.qi.end(); iti++, itj++, itv++)
        {
            qptemp[*iti].push_back(pair<int, double>(*itj,*itv));
            qpnz++;
            if(*iti != *itj)
            {
                qptemp[*itj].push_back(pair<int, double>(*iti,*itv));
                qpnz++;
            }
        }
        if(!vars.qi.empty())
        {
            qpv = new double[qpnz];
            qpind = new int[qpnz];
            
            qpnz=0;
            for(int i = 0; i < int(nc); i++)
            {
                qpbeg[i] = qpnz;
                qpnum[i] = int(qptemp[i].size());
                for(int j = 0; j < int(qptemp[i].size()); j++)
                {
                    qpind[qpnz] = qptemp[i][j].first;
                    qpv[qpnz] = 2.0*qptemp[i][j].second;
                    qpnz++;
                }
            }
            status = CPXcopyquad(d->env, d->lp, qpbeg, qpnum, qpind, qpv);
            delete[] qpbeg;
            delete[] qpnum;
            delete[] qpind;
            delete[] qpv;
        }
        if ( status )
        {
            printf("QP problem!\n");
            return 1;
        }
    }
    //else
        //printf("Coefs added!\n");
    bcreated = true;

    return 0;
}
Beispiel #9
0
int cg_solver(int m, MyRow* rows)
{
   CPXENVptr     env = NULL;
   CPXLPptr      model = NULL;
   int           status = 0;
   int           error = 0;
   int           i, j;
   int           cur_numrows, cur_numcols;
   int           n_cuts, cut;

   int       solstat;
   double    objval;
   double   *x;
   double   *z;
   int      *cstat;
 
   int      n0 = rows[0].n;      
   int      n1 = rows[0].n+m-1;  /// One slack variable for constraint
   int      h = (m-1)*n0 + m-1;  /// Number of nonzeros

   double   obj[n1];

   double   rhs[m-1];    /// The first row is for the cost vector
   char     sense[m-1];

   int      jnd[h];
   int      ind[h];
   double   val[h];

   int      idx = 0;

   int*     rmatbeg;
   int*     rmatind;
   double*  rmatval;
   double*  b_bar;
   char*    gc_sense;
   double*  gc_rhs;

   /// Create environment
   env = CPXopenCPLEX (&status);
   if ( env == NULL ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment. Status: %d\n", status);
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto QUIT;
   }

   /// Disable presolve
   POST_CMD( CPXsetintparam (env, CPX_PARAM_PREIND, CPX_OFF) );
   
   /// Create problem
   model = CPXcreateprob (env, &error, "gomory");
   if (error) goto QUIT;

   /// Minimization problem
   POST_CMD( CPXchgobjsen (env, model, CPX_MIN) );
   
   /// Add rows (remember first row is cost vector)
   for ( i = 0; i < m-1; ++i ) {
      sense[i]='E';
      rhs[i] = rows[i+1].rhs;
   }
   POST_CMD( CPXnewrows(env, model, m-1, rhs, sense, NULL, NULL) );
   
   /// Add problem variables 
   for ( j = 0; j < n0; ++j ) 
      obj[j] = rows[0].lhs[j];
   /// Add slack variables 
   for ( j = n0; j < n1; ++j ) 
      obj[j] = 0;
   POST_CMD( CPXnewcols(env, model, n1, obj, NULL, NULL, NULL, NULL) );

   /// Write the full matrix A into the LP (WARNING: should use only nonzeros entries)
   for ( i = 1; i < m; ++i ) {
      for ( j = 0; j < n0; ++j ) {
         jnd[idx] = i-1;
         ind[idx] = rows[i].ind[j];
         val[idx] = rows[i].lhs[j];
         idx++;
      }
      /// Add a slack variable per constraint
      jnd[idx] = i-1;
      ind[idx] = n0+i-1;
      val[idx] = 1.0;
      idx++;
   }
   POST_CMD( CPXchgcoeflist(env, model, idx, jnd, ind, val) );

   /// Optimize the problem
   POST_CMD( CPXlpopt(env, model) );

   /// Check the results
   cur_numrows = CPXgetnumrows (env, model);
   cur_numcols = CPXgetnumcols (env, model);

   x =  (double *) malloc (cur_numcols * sizeof(double));
   z =  (double *) malloc (cur_numcols * sizeof(double));
   cstat = (int *) malloc (cur_numcols * sizeof(int));

   b_bar = (double *) malloc (cur_numrows * sizeof(double));

   POST_CMD( CPXsolution (env, model, &solstat, &objval, x, NULL, NULL, NULL) );
   if ( solstat != 1 ) {
      printf("The solver did not find an optimal solution\nSolver status code: %d\n",solstat);
      exit(0);
   }

   /// Write the output to the screen 
   printf ("\nSolution status = %d\t\t", solstat);
   printf ("Solution value  = %f\n\n", objval);

   /// If the solution is integer, is the optimum -> exit the loop
   if ( isInteger(cur_numcols, x) ) {
      fprintf(stdout,"The solution is already integer!\n");
      goto QUIT;
   }

   /// Dump the problem model to 'gomory.lp' for debbuging
   POST_CMD( CPXwriteprob(env, model, "gomory.lp", NULL) );

   /// Get the base statuses
   POST_CMD( CPXgetbase(env, model, cstat, NULL) );

   print_solution(cur_numcols, x, cstat);

   printf("\nOptimal base inverted matrix:\n");
   for ( i = 0; i < cur_numrows; ++i ) {
      b_bar[i] = 0;
      POST_CMD( CPXbinvrow(env, model, i, z) );
      for ( j = 0; j < cur_numrows; ++j ) {
         printf("%.1f ", z[j]);
         b_bar[i] += z[j]*rhs[j];
      }
      printf("\n");
   }

   printf("\nOptimal solution (non basic variables are equal to zero):\n");
   idx = 0;     /// Compute the nonzeros
   n_cuts = 0;  /// Number of fractional variables (cuts to be generated)
   for ( i = 0; i < m-1; ++i ) {
      POST_CMD( CPXbinvarow(env, model, i, z) );
      for ( j = 0; j < n1; ++j ) {
         if ( z[j] >= 0 )
            printf("+");
         printf("%.1f x%d ", z[j], j+1);
         if ( floor(z[j]+0.5) != 0 )
            idx++;
      }
      printf("= %.1f\n", b_bar[i]);
      /// Count the number of cuts to be generated
      if ( floor(b_bar[i]) != b_bar[i] ) 
         n_cuts++;
   }

   /// Allocate memory for the new data structure
   gc_sense = (char*)   malloc ( n_cuts * sizeof(char) ); 
   gc_rhs   = (double*) malloc ( n_cuts * sizeof(double) ); 
   rmatbeg  = (int*)    malloc ( n_cuts * sizeof(int) ); 
   rmatind  = (int*)    malloc (    idx * sizeof(int) ); 
   rmatval  = (double*) malloc (    idx * sizeof(double) ); 

   printf("\nGenerate Gomory cuts:\n");
   idx = 0;
   cut = 0;  /// Index of cut to be added
   for ( i = 0; i < m-1; ++i ) 
      if ( floor(b_bar[i]) != b_bar[i] ) {
         printf("Row %d gives cut ->   ", i+1);
         POST_CMD( CPXbinvarow(env, model, i, z) );
         rmatbeg[cut] = idx;
         for ( j = 0; j < n1; ++j ) {
            z[j] = floor(z[j]); /// DANGER!
            if ( z[j] != 0 ) {
               rmatind[idx] = j;
               rmatval[idx] = z[j];
               idx++;
            }
            /// Print the cut
            if ( z[j] >= 0 )
               printf("+");
            printf("%.1f x%d ", z[j], j+1);
         }
         gc_rhs[cut] = floor(b_bar[i]); /// DANGER!
         gc_sense[cut] = 'L';
         printf("<= %.1f\n", gc_rhs[cut]);
         cut++;
      }

   /// Add the new cuts
   POST_CMD( CPXaddrows (env, model, 0, 
            n_cuts, idx, gc_rhs, gc_sense, 
            rmatbeg, rmatind, rmatval, 
            NULL, NULL) );

   /// Solve the new LP
   POST_CMD( CPXlpopt(env, model) );

   /// Check the results
   cur_numrows = CPXgetnumrows (env, model);
   cur_numcols = CPXgetnumcols (env, model);

   POST_CMD( CPXsolution (env, model, &solstat, &objval, x, NULL, NULL, NULL) );

   if ( solstat != 1 ) {
      printf("The solver did not find an optimal solution\nSolver status code: %d\n",solstat);
      exit(0);
   }
   /// Write the output to the screen 
   printf ("\nSolution status = %d\n", solstat);
   printf ("Solution value = %f\n\n", objval);

   POST_CMD( CPXgetbase(env, model, cstat, NULL) );

   print_solution(cur_numcols, x, cstat);

   free_and_null ((char **) &x);
   free_and_null ((char **) &z);
   free_and_null ((char **) &cstat);
   free_and_null ((char **) &rmatbeg);
   free_and_null ((char **) &rmatind);
   free_and_null ((char **) &rmatval);

QUIT:
   free_and_null ((char **) &x);
   free_and_null ((char **) &z);
   free_and_null ((char **) &cstat);

   if ( error ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      CPXgeterrorstring (env, error, errmsg);
      fprintf (stderr, "%s", errmsg);
   }

   /* Free up the problem as allocated by CPXcreateprob, if necessary */
   if ( model != NULL ) {
      status = CPXfreeprob (env, &model);
      if ( status ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status);
      }
   }

   /* Free up the CPLEX environment, if necessary */
   if ( env != NULL ) {
      status = CPXcloseCPLEX (&env);

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

   return (status);
}