Exemplo n.º 1
0
long GenModelCplex::ChangeBulkNz(int count, int* rind, int* cind, double * vals)
{
    if(!bcreated)
        return ThrowError("ChangeBulkNz() not available : Problem not created yet");
    CplexData* d = (CplexData*)solverdata;
    
    for(long i = 0; i < count; i++)
    {
        bool found = false;
        for(long j = 0; j < int(consts[rind[i]].cols.size()); j++)
        {
            if(consts[rind[i]].cols[j] == cind[i])
            {
                consts[rind[i]].coefs[j] = vals[i];
                found = true;
                break;
            }
        }
        if(!found)
            consts[rind[i]].AddNz(cind[i], vals[i]);
    }
    
    CPXchgcoeflist(d->env, d->lp, count, rind, cind, vals);
    
    return 0;
}
Exemplo n.º 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;

}
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);
} 
Exemplo n.º 4
0
void
DDSIP_DetEqu ()
{
    CPXLPptr det_equ;

    int status, scen, i, j, k, nzcnt_row, ranged = 0;
    char probname[] = "sipout/det_equ.lp.gz";
    double *scaled_obj_coef = NULL;
    char *sense = NULL, *sense_sorted = NULL;
    char **scen_spec_rowname = NULL;
    char **scen_spec_colname = NULL;
    char **rowname = NULL, *rownamestore = NULL;
    char **colname = NULL, *colnamestore = NULL;
    int rowstorespace, rowsurplus;
    int colstorespace, colsurplus;
    char *string1 = NULL, *string2 = NULL;
    double *lb = NULL, *lb_sorted = NULL;
    double *ub = NULL, *ub_sorted = NULL;
    double *rng = NULL, *rng_sorted = NULL;
    char *vartype = NULL, *vartype_sorted = NULL;
    int *colindex_sorted = NULL, *colindex_revers = NULL;
    double *value = NULL;
    double *det_equ_rhs = NULL;
    double *base_rhs = NULL;
    int nzcnt=0, *rmatbeg=NULL, *rmatind=NULL, *rmatbeg_stage=NULL, *rmatind_stage=NULL, *rowindex=NULL;
    double *rmatval=NULL, *rmatval_stage=NULL;
    double time_start, time_end;
    time_start = DDSIP_GetCpuTime ();
    k = abs(DDSIP_param->riskmod);
    if (k > 2 && k != 4)
    {
        fprintf (stderr,
             "\nNot building deterministic equivalent, not available for risk model %d\n",DDSIP_param->riskmod);
        fprintf (DDSIP_outfile,
             "\nNot building deterministic equivalent, not available for risk model %d\n",DDSIP_param->riskmod);
        return;
    }
    if (DDSIP_data->seccon)
        det_equ_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_Imax(DDSIP_Imax(DDSIP_data->seccon, DDSIP_param->scenarios), DDSIP_data->firstcon),"det_equ_rhs(DetEqu)");
    else
    {
        fprintf (stderr,"XXX ERROR: no second stage contraints, got DDSIP_data->seccon=%d.\n",DDSIP_data->seccon);
        return;
    }

    fprintf (stderr,
             "\nBuilding deterministic equivalent.\nWorks only for expectation-based models.\n");

    colstorespace = DDSIP_data->novar * 255;
    rowstorespace = DDSIP_data->nocon * 255;
    if (!(sense = (char *) DDSIP_Alloc (sizeof (char), DDSIP_data->nocon, "sense(DetEqu)")) ||
        !(sense_sorted = (char *) DDSIP_Alloc (sizeof (char), DDSIP_Imax(DDSIP_param->scenarios, DDSIP_Imax(DDSIP_data->firstcon,DDSIP_data->seccon)), "sense_sorted(DetEqu)")) ||
        !(base_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_data->nocon,"base_rhs(DetEqu)")) ||
        !(scaled_obj_coef = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar, DDSIP_data->secvar), "base_rhs(DetEqu)")) ||
        !(colname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_data->novar,"base_rhs(DetEqu)")) ||
        !(scen_spec_colname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "scen_spec_colname(DetEqu)")) ||
        !(colnamestore = (char *) DDSIP_Alloc (sizeof (char), colstorespace, "colnamestore(DetEqu)")) ||
        !(rowname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_data->nocon, "rowname(DetrEqu)")) ||
        !(scen_spec_rowname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_Imax(DDSIP_param->scenarios, DDSIP_Imax(DDSIP_data->firstcon,DDSIP_data->seccon)), "scen_spec_rowname(DetEqu)")) ||
        !(rownamestore = (char *) DDSIP_Alloc (sizeof (char), rowstorespace, "rownamestore(DetEqu)")) ||
        !(lb = (double *) DDSIP_Alloc (sizeof (double), DDSIP_data->novar, "lb(DetEqu)")) ||
        !(lb_sorted = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "lb_sorted(DetEqu)")) ||
        !(ub = (double *) DDSIP_Alloc (sizeof (double), DDSIP_data->novar, "ub(DetEqu)")) ||
        !(ub_sorted = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "ub_sorted(DetEqu)")) ||
        !(vartype = (char *) DDSIP_Alloc (sizeof (char), DDSIP_data->novar, "vartype(DetEqu)")) ||
        !(vartype_sorted = (char *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "vartype_sorted(DetEqu)")) ||
        !(colindex_sorted = (int *) DDSIP_Alloc (sizeof (int), DDSIP_data->novar, "colindex_sorted(DetEqu)")) ||
        !(rowindex = (int *) DDSIP_Alloc (sizeof (int), DDSIP_Imax(DDSIP_data->firstcon, DDSIP_data->seccon), "rowindex(DetEqu)")))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }

    // get problem data
    /*____________________________________________________________________________________*/
    if((status = CPXgetcolname (DDSIP_env, DDSIP_lp, colname, colnamestore,
                            colstorespace, &colsurplus, 0, DDSIP_data->novar - 1)) ||
       (status = CPXgetrowname (DDSIP_env, DDSIP_lp, rowname, rownamestore,
                            rowstorespace, &rowsurplus, 0, DDSIP_data->nocon - 1)) ||
       (status = CPXgetsense (DDSIP_env, DDSIP_lp, sense, 0, DDSIP_data->nocon - 1)) ||
       (status = CPXgetrhs (DDSIP_env, DDSIP_lp, base_rhs, 0, DDSIP_data->nocon - 1)) ||
       (status = CPXgetlb (DDSIP_env, DDSIP_lp, lb, 0, DDSIP_data->novar - 1)) ||
       (status = CPXgetub (DDSIP_env, DDSIP_lp, ub, 0, DDSIP_data->novar - 1)) ||
       (status = CPXgetctype (DDSIP_env, DDSIP_lp, vartype, 0, DDSIP_data->novar - 1)))
    {
        fprintf (stderr, "Coud not get problem data, returned %d\n", status);
        goto FREE;
    }
    // check whether there are ranged rows
    for (j=0; j<DDSIP_data->nocon; j++)
    {
        if (sense[j] == 'R')
        {
            ranged = 1;
	    break;
        }
    } 
    if (ranged)
    {
        if (!(rng = (double *) DDSIP_Alloc (sizeof (double), DDSIP_data->nocon, "rng(DetEqu)")) ||
            !(rng_sorted = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstcon,DDSIP_data->seccon), "rng_sorted(DetEqu)")))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        if ((status = CPXgetrngval (DDSIP_env, DDSIP_lp, rng, 0, DDSIP_data->nocon-1)))
        {
            fprintf (stderr, "Coud not get problem ranges, returned %d\n", status);
            goto FREE;
        }
    }
    /*____________________________________________________________________________________*/

    // create empty problem
    det_equ = CPXcreateprob (DDSIP_env, &status, probname);
    if (status)
    {
        fprintf (stderr, "CPXcreateprob returned %d\n", status);
        goto FREE;
    }
    // add (original) first-stage variables
    for (j = 0; j < DDSIP_data->firstvar; j++)
    {
        vartype_sorted[j]   = vartype[DDSIP_bb->firstindex[j]];
        lb_sorted[j]        = lb[DDSIP_bb->firstindex[j]];
        ub_sorted[j]        = ub[DDSIP_bb->firstindex[j]];
        if (DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
            scaled_obj_coef[j]  = DDSIP_data->obj_coef[DDSIP_bb->firstindex[j]];
        scen_spec_colname[j]= colname[DDSIP_bb->firstindex[j]];
    }
    if ((status = CPXnewcols (DDSIP_env, det_equ, DDSIP_data->firstvar, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
    {
        fprintf (stderr, "CPXnewcols returned %d for first-stage variables\n", status);
        goto FREE;
    }
    // add (original) second-stage variables for all scenarios
    for (j = 0; j < DDSIP_data->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_data->secvar; j++)
        {
            if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
            {
                fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                goto FREE;
            }
            // append scenario index to colname
            string1 = colname[DDSIP_bb->secondindex[j]];
            sprintf (string2, "%sSC%.3d", string1, scen+1);
            scen_spec_colname[j] = string2;
            if (DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
                scaled_obj_coef[j] = DDSIP_data->prob[scen] * DDSIP_data->obj_coef[DDSIP_bb->secondindex[j]];
        }
        if ((status = CPXnewcols (DDSIP_env, det_equ, DDSIP_data->secvar, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
        {
            fprintf (stderr, "CPXnewcols returned %d for second-stage variables of scenario %d\n", status, scen+1);
            goto FREE;
        }
        for (j = 0; j < DDSIP_data->secvar; j++)
            DDSIP_Free ((void **) &(scen_spec_colname[j]));
    }
    // add second-stage variable for objective value of the scenarios
    if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }
    scen_spec_colname[0] = string2;
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        vartype_sorted[0] = 'C';
        lb_sorted[0]      = -DDSIP_infty;
        ub_sorted[0]      =  DDSIP_infty;
        sprintf (string2, "DDSIPobj_SC%.3d", scen+1);
        if (!DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
            scaled_obj_coef[0] = DDSIP_data->prob[scen];
        else
            scaled_obj_coef[0] = 0.;
        if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
        {
            fprintf (stderr, "CPXnewcols returned %d for second-stage variable  DDSIPobj_SC%.3d\n", status, scen+1);
            goto FREE;
        }
    }
    // add the additional variables needed for risk models ///////////////////////////////////////
    if (DDSIP_param->riskmod)
    {
        switch (abs(DDSIP_param->riskmod))
        {
          case 1:  // Expected excess
             // one continuous second-stage variable for each scenario
             for (scen = 0; scen < DDSIP_param->scenarios; scen++)
             {
                vartype_sorted[0] = 'C';
                lb_sorted[0]      = 0.;
                ub_sorted[0]      = DDSIP_infty;
                sprintf (string2, "DDSIP_expexc_SC%.3d", scen+1);
                if (DDSIP_param->riskmod > 0)
                    scaled_obj_coef[0] = DDSIP_param->riskweight*DDSIP_data->prob[scen];
                else if (DDSIP_param->riskmod < 0)
                    scaled_obj_coef[0] = DDSIP_data->prob[scen];
                else
                    scaled_obj_coef[0] = 0.;
                if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                                lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
                {
                    fprintf (stderr, "CPXnewcols returned %d for second-stage variable  %s\n", status, string2);
                    goto FREE;
                }
             }  
             break;
          case 2:  // Excess Probability
             // one binary second-stage variable for each scenario
             for (scen = 0; scen < DDSIP_param->scenarios; scen++)
             {
                vartype_sorted[0] = 'B';
                lb_sorted[0]      = 0.;
                ub_sorted[0]      = 1.;
                sprintf (string2, "DDSIP_excprob_SC%.3d", scen+1);
                if (DDSIP_param->riskmod > 0)
                    scaled_obj_coef[0] = DDSIP_param->riskweight*DDSIP_data->prob[scen];
                else if (DDSIP_param->riskmod < 0)
                    scaled_obj_coef[0] = DDSIP_data->prob[scen];
                else
                    scaled_obj_coef[0] = 0.;
                if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                                lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
                {
                    fprintf (stderr, "CPXnewcols returned %d for second-stage variable  %s\n", status, string2);
                    goto FREE;
                }
             }  
             break;
          case 4:  // Worst Case Costs
             // one continuous first-stage variable
                vartype_sorted[0] = 'C';
                lb_sorted[0]      = -DDSIP_infty;
                ub_sorted[0]      =  DDSIP_infty;
                if (DDSIP_param->prefix)
                {
                    if (!(strlen(DDSIP_param->prefix)))
                    {
                        fprintf (stderr," *** ERROR: The prefix for the first stage variables has to have a positive length.\n");
                        exit (1);
                    }
                    sprintf (string2, "%sDDSIP_n_aux01",DDSIP_param->prefix);
                }
                else
                {
                    if (!(strlen(DDSIP_param->postfix)))
                    {
                        fprintf (stderr," *** ERROR: The postfix for the first stage variables has to have a positive length.\n");
                        exit (1);
                    }
                    sprintf (string2, "DDSIP_worstc_%s",DDSIP_param->postfix);
                }
                if (DDSIP_param->riskmod > 0)
                    scaled_obj_coef[0] = DDSIP_param->riskweight;
                else if (DDSIP_param->riskmod < 0)
                    scaled_obj_coef[0] = 1.;
                else
                    scaled_obj_coef[0] = 0.;
                if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                                lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
                {
                    fprintf (stderr, "CPXnewcols returned %d for second-stage variable  %s\n", status, string2);
                    goto FREE;
                }
        }
    }
    DDSIP_Free ((void **) &(scen_spec_colname[0]));
        
    ///////enter stochastic cost coefficients in case of deteqType 1 //////////////////////////////
    if (DDSIP_param->stoccost && DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
    {
        for (j = 0; j < DDSIP_param->stoccost; j++)
        {
            scaled_obj_coef[j] = 0.0;
            if ((colindex_sorted[j] = DDSIP_bb->firstindex_reverse[DDSIP_data->costind[j]]))
                 colindex_sorted[j] = DDSIP_data->firstvar + DDSIP_bb->secondindex_reverse[DDSIP_data->costind[j]];
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    scaled_obj_coef[j] = DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
                else
                    scaled_obj_coef[j] += DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
            }
            status = CPXchgobj (DDSIP_env, det_equ, DDSIP_param->stoccost, colindex_sorted, scaled_obj_coef);
            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 (colindex_sorted[j] >= DDSIP_data->firstvar)
                    colindex_sorted[j] += DDSIP_data->secvar;
            }
        }
    }
    //
    // free arrays needeed only for columns
    DDSIP_Free ((void **) &(vartype));
    DDSIP_Free ((void **) &(colname));
    DDSIP_Free ((void **) &(colnamestore));
    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 **) &(scaled_obj_coef));
    //
    // get problem matrix coefficients
    // query the length needed for storage of coefficients
    CPXgetrows(DDSIP_env, DDSIP_lp, &nzcnt, rmatbeg, rmatind, rmatval, 0, &rowsurplus, 0, DDSIP_data->nocon-1);
    nzcnt = -rowsurplus;
    if (!(rmatbeg = (int *) DDSIP_Alloc (sizeof (int), DDSIP_data->nocon, "rmatbeg(DetEqu)")) ||
        !(rmatind = (int *) DDSIP_Alloc (sizeof (int), DDSIP_Imax(nzcnt, DDSIP_param->stocmat), "rmatind(DetEqu)")) ||
        !(rmatval = (double *) DDSIP_Alloc (sizeof (double), nzcnt, "rmatval(DetEqu)")))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }
    CPXgetrows(DDSIP_env, DDSIP_lp, &nzcnt, rmatbeg, rmatind, rmatval, nzcnt, &rowsurplus, 0, DDSIP_data->nocon-1);

    printf(" got %d elements of the matrix\n", nzcnt);

    k = DDSIP_Imax(nzcnt + DDSIP_param->stocmat, DDSIP_param->scenarios*(DDSIP_data->novar+1));
    if (!(rmatbeg_stage = (int *) DDSIP_Alloc (sizeof (int), DDSIP_Imax(DDSIP_param->scenarios, DDSIP_Imax(DDSIP_data->firstcon, DDSIP_data->seccon)), "rmatbeg_stage(DetEqu)")) ||
        !(rmatind_stage = (int *) DDSIP_Alloc (sizeof (int), k, "rmatind_stage(DetEqu)")) ||
        !(rmatval_stage = (double *) DDSIP_Alloc (sizeof (double), k, "rmatval_stage(DetEqu)")))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }

    // add first-stage constraints
    k = 0;
    for (j = 0; j < DDSIP_data->firstcon; j++)
    {
        sense_sorted[j] = sense[DDSIP_bb->firstrowind[j]];
        det_equ_rhs[j] = base_rhs[DDSIP_bb->firstrowind[j]];
        scen_spec_rowname[j] = rowname[DDSIP_bb->firstrowind[j]];
	rmatbeg_stage[j] = k;
	if (DDSIP_bb->firstrowind[j] == DDSIP_data->nocon -1)
            nzcnt_row = nzcnt - rmatbeg[DDSIP_data->nocon -1];
        else
            nzcnt_row = rmatbeg[DDSIP_bb->firstrowind[j]+1] - rmatbeg[DDSIP_bb->firstrowind[j]];
	for (i = 0; i < nzcnt_row; i++)
        {
            rmatind_stage[k + i] = DDSIP_bb->firstindex_reverse[rmatind[rmatbeg[DDSIP_bb->firstrowind[j]] + i]];
            rmatval_stage[k + i] = rmatval[rmatbeg[DDSIP_bb->firstrowind[j]] + i];
        }
	k += nzcnt_row;
    }
    if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_data->firstcon, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
    {
        fprintf (stderr, "CPXaddrows returned %d for first-stage constraints\n", status);
        goto FREE;
    }
    if (ranged)
    {
        for (j = 0; j < DDSIP_data->firstcon; j++)
        {
            rng_sorted[j] = rng[DDSIP_bb->firstrowind[j]];
            rowindex[j]   = j;
        }
        if((status = CPXchgrngval(DDSIP_env, det_equ, DDSIP_data->firstcon, rowindex, rng_sorted)))
        {
            fprintf (stderr, "CPXchgrngval returned %d for first-stage constraints\n", status);
            goto FREE;
        }
    }

    // add second-stage constraints
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        k = 0;
        for (j = 0; j < DDSIP_data->seccon; j++)
        {
            sense_sorted[j] = sense[DDSIP_bb->secondrowind[j]];
            det_equ_rhs[j] = base_rhs[DDSIP_bb->secondrowind[j]];
            if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
            {
                fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                goto FREE;
            }
            // append scenario index to colname
            string1 = rowname[DDSIP_bb->secondrowind[j]];
            sprintf (string2, "%sSC%.3d", string1, scen+1);
            scen_spec_rowname[j] = string2;
            rmatbeg_stage[j] = k;
            if (DDSIP_bb->secondrowind[j] == DDSIP_data->nocon -1)
                nzcnt_row = nzcnt - rmatbeg[DDSIP_data->nocon -1];
            else
            {
                nzcnt_row = rmatbeg[DDSIP_bb->secondrowind[j]+1] - rmatbeg[DDSIP_bb->secondrowind[j]];

            }
            for (i = 0; i < nzcnt_row; i++)
            {
                if (DDSIP_bb->firstindex_reverse[rmatind[rmatbeg[DDSIP_bb->secondrowind[j]] + i]] < 0)
                    rmatind_stage[k + i] = DDSIP_data->firstvar + scen*DDSIP_data->secvar + DDSIP_bb->secondindex_reverse[rmatind[rmatbeg[DDSIP_bb->secondrowind[j]] + i]];
                else
                    rmatind_stage[k + i] = DDSIP_bb->firstindex_reverse[rmatind[rmatbeg[DDSIP_bb->secondrowind[j]] + i]];
                rmatval_stage[k + i] = rmatval[rmatbeg[DDSIP_bb->secondrowind[j]] + i];
            }
            k += nzcnt_row;
        }
        ///////enter stochastic rhs entries//////////////////////////////////////////////////////
        for (j=0; j< DDSIP_param->stocrhs; j++)
        {
            det_equ_rhs[DDSIP_bb->secondrowind_reverse[DDSIP_data->rhsind[j]]] = DDSIP_data->rhs[scen * DDSIP_param->stocrhs + j];
        }

        if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_data->seccon, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
        {
            fprintf (stderr, "CPXaddrows returned %d for second-stage constraints scenario %d\n", status, scen+1);
            goto FREE;
        }
        for (j = 0; j < DDSIP_data->seccon; j++)
            DDSIP_Free ((void **) &(scen_spec_rowname[j]));
        if (ranged)
        {
            for (j = 0; j < DDSIP_data->seccon; j++)
            {
                rng_sorted[j] = rng[DDSIP_bb->secondrowind[j]];
                rowindex[j]   = DDSIP_data->firstcon + scen * DDSIP_data->seccon + j;
            }
            if ((status = CPXchgrngval(DDSIP_env, det_equ, DDSIP_data->seccon, rowindex, rng_sorted)))
            {
                fprintf (stderr, "CPXchgrngval returned %d for first-stage constraints\n", status);
                goto FREE;
            }
        }
    }
    ///////enter stochastic matrix entries//////////////////////////////////////////////////////
    if (DDSIP_param->stocmat)
    {

        if (!(value = (double *) calloc (DDSIP_param->stocmat, sizeof (double))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        for (j = 0; j < DDSIP_param->stocmat; j++)
        {
            if ((colindex_sorted[j] = DDSIP_bb->firstindex_reverse[DDSIP_data->matcol[j]]))
                 colindex_sorted[j] = DDSIP_data->firstvar + DDSIP_bb->secondindex_reverse[DDSIP_data->matcol[j]];
            rmatind[j] = DDSIP_data->firstcon + DDSIP_bb->secondrowind_reverse[DDSIP_data->matrow[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, rmatind, colindex_sorted, value);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu chgcoeflist returned %d: %s\n", status, errmsg);
            }
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                rmatind[j] += DDSIP_data->seccon;
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    colindex_sorted[j] += DDSIP_data->secvar;
            }
        }
        DDSIP_Free ((void **) &(value));
    }

    // add second-stage equations for the objective values of the scenarios
    k = 0;
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        sense_sorted[scen] = 'E';
        det_equ_rhs[scen] = 0.;
        if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        sprintf (string2, "DDSIP_o_SC%.3d", scen+1);
        scen_spec_rowname[scen] = string2;
        rmatbeg_stage[scen] = k;
        nzcnt_row = DDSIP_data->novar + 1;
        for (i = 0; i < DDSIP_data->novar; i++)
        {
            if (DDSIP_bb->firstindex_reverse[i] < 0)
            {
                rmatind_stage[k + i] = DDSIP_data->firstvar + scen*DDSIP_data->secvar + DDSIP_bb->secondindex_reverse[i];
            }
            else
            {
                rmatind_stage[k + i] = DDSIP_bb->firstindex_reverse[i];
            }
            rmatval_stage[k + i] = DDSIP_data->obj_coef[i];
        }
        rmatind_stage[k + DDSIP_data->novar] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen;
        rmatval_stage[k + DDSIP_data->novar] = -1.;
        k += nzcnt_row;
    }
    if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
    {
        fprintf (stderr, "CPXaddrows returned %d for second-stage objective constraints\n", status);
        goto FREE;
    }
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        DDSIP_Free ((void **) &(scen_spec_rowname[scen]));
    }
    ///////enter stochastic cost coefficients in the objective equations //////////////////////////////
    if (DDSIP_param->stoccost)
    {
        if (!(value = (double *) calloc (DDSIP_param->stoccost, sizeof (double))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if ((colindex_sorted[j] = DDSIP_bb->firstindex_reverse[DDSIP_data->costind[j]]) < 0)
                     colindex_sorted[j] = DDSIP_data->firstvar + scen * DDSIP_data->secvar +DDSIP_bb->secondindex_reverse[DDSIP_data->costind[j]];
                rmatind[j] = DDSIP_data->firstcon + DDSIP_param->scenarios*DDSIP_data->seccon + scen;
                value[j] = DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
            }
            status = CPXchgcoeflist (DDSIP_env, det_equ, DDSIP_param->stoccost, rmatind, colindex_sorted, value);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu chgcoeflist returned %d: %s\n", status, errmsg);
            }
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                rmatind[j] += DDSIP_data->seccon;
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    colindex_sorted[j] += DDSIP_data->secvar;
            }
        }
        DDSIP_Free ((void **) &(value));
    }
    // add second-stage equations for the risk models //////////////////////////////////
    switch (abs(DDSIP_param->riskmod))
    {
      case 1:  // Expected excess
         k = 0;
         for (scen = 0; scen < DDSIP_param->scenarios; scen++)
         {
             sense_sorted[scen] = 'L';
             det_equ_rhs[scen]  = DDSIP_param->risktarget;
             if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
             {
                 fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                 goto FREE;
             }
             sprintf (string2, "DDSIP_exp_excess_SC%.3d", scen+1);
             scen_spec_rowname[scen] = string2;
             rmatbeg_stage[scen] = k;
             nzcnt_row = 2;
             rmatind_stage[k]     = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen; 
             rmatval_stage[k]     = 1.;
             rmatind_stage[k + 1] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + DDSIP_param->scenarios + scen; 
             rmatval_stage[k + 1] = -1.;
             k += nzcnt_row;
         }
         if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
         {
             fprintf (stderr, "CPXaddrows returned %d for second-stage risk constraints\n", status);
             goto FREE;
         }
         break;
      case 2:  // Excess probability
         k = 0;
         for (scen = 0; scen < DDSIP_param->scenarios; scen++)
         {
             sense_sorted[scen] = 'L';
             det_equ_rhs[scen]  = DDSIP_param->risktarget;
             if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
             {
                 fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                 goto FREE;
             }
             sprintf (string2, "DDSIP_excess_prob_SC%.3d", scen+1);
             scen_spec_rowname[scen] = string2;
             rmatbeg_stage[scen] = k;
             nzcnt_row = 2;
             rmatind_stage[k]     = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen; 
             rmatval_stage[k]     = 1.;
             rmatind_stage[k + 1] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + DDSIP_param->scenarios + scen; 
             rmatval_stage[k + 1] = -DDSIP_param->riskM;
             k += nzcnt_row;
         }
         if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
         {
             fprintf (stderr, "CPXaddrows returned %d for second-stage risk constraints\n", status);
             goto FREE;
         }
         break;
      case 4:  // Worst case cost
         k = 0;
         for (scen = 0; scen < DDSIP_param->scenarios; scen++)
         {
             sense_sorted[scen] = 'L';
             det_equ_rhs[scen]  = 0.;
             if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
             {
                 fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                 goto FREE;
             }
             sprintf (string2, "DDSIP_worst_case_SC%.3d", scen+1);
             scen_spec_rowname[scen] = string2;
             rmatbeg_stage[scen] = k;
             nzcnt_row = 2;
             rmatind_stage[k]     = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen; 
             rmatval_stage[k]     = 1.;
             rmatind_stage[k + 1] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + DDSIP_param->scenarios; 
             rmatval_stage[k + 1] = -1.;
             k += nzcnt_row;
         }
         if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
         {
             fprintf (stderr, "CPXaddrows returned %d for second-stage risk constraints\n", status);
             goto FREE;
         }
         break;
    }
    for (j = 0; j < DDSIP_param->scenarios; j++)
        DDSIP_Free ((void **) &(scen_spec_rowname[j]));

    time_end = DDSIP_GetCpuTime ();
    fprintf (DDSIP_outfile, " %6.2f sec  for building deterministic equivalent\n",time_end-time_start);

    status = CPXwriteprob (DDSIP_env, det_equ, probname, NULL);
    if (status)
    {
        fprintf (DDSIP_outfile, " *** Deterministic equivalent not written successfully, status = %d\n", status);
        printf  (" *** Deterministic equivalent not written successfully, status = %d\n", status);
    }
    else
    {
        fprintf (DDSIP_outfile, " *** Deterministic equivalent %s written successfully\n", probname);
        printf  (" *** Deterministic equivalent %s written successfully\n", probname);
    }
    status = CPXfreeprob (DDSIP_env, &det_equ);
    time_start = DDSIP_GetCpuTime ();
    fprintf (DDSIP_outfile, " %6.2f sec  for writing deterministic equivalent\n",time_start-time_end);

FREE:
    DDSIP_Free ((void **) &(sense));
    DDSIP_Free ((void **) &(sense_sorted));
    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 **) &(base_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 **) &(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));
    DDSIP_Free ((void **) &(rmatbeg));
    DDSIP_Free ((void **) &(rmatind));
    DDSIP_Free ((void **) &(rmatval));
    DDSIP_Free ((void **) &(rmatbeg_stage));
    DDSIP_Free ((void **) &(rmatind_stage));
    DDSIP_Free ((void **) &(rmatval_stage));
    DDSIP_Free ((void **) &(rowindex));
    if (ranged)
    {
        DDSIP_Free ((void **) &(rng));
        DDSIP_Free ((void **) &(rng_sorted));
    }
    return;
}
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 */
Exemplo n.º 6
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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
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);
}