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