//========================================================================== // This function solves the expected value problem int DDSIP_ExpValProb (void) { int status, j, mipstatus, nodes_1st = -1; int wall_hrs, wall_mins,cpu_hrs, cpu_mins; double objval, bobjval, time_start, time_end, wall_secs, cpu_secs, gap; char fname[DDSIP_ln_fname]; double *mipx = (double *) DDSIP_Alloc (sizeof (double), (DDSIP_bb->firstvar + DDSIP_bb->secvar), "mipx(ExpValProb)"); printf ("Solving expected value problem\n"); if (DDSIP_param->outlev) fprintf (DDSIP_bb->moreoutfile, "Solving expected value problem...\n"); status = DDSIP_ChgProb (-1, 0); if (status) { fprintf (stderr, "ERROR: Failed to change problem \n"); goto TERMINATE; } if (DDSIP_param->files > 1) { sprintf (fname, "%s/ev%s", DDSIP_outdir, DDSIP_param->coretype); status = CPXwriteprob (DDSIP_env, DDSIP_lp, fname, NULL); if (status) { fprintf (stderr, "ERROR: Failed to write problem\n"); goto TERMINATE; } } // New cplex parameters if (DDSIP_param->cpxnoeev) { status = DDSIP_SetCpxPara (DDSIP_param->cpxnoeev, DDSIP_param->cpxeevisdbl, DDSIP_param->cpxeevwhich, DDSIP_param->cpxeevwhat); if (status) { fprintf (stderr, "ERROR: Failed to set CPLEX parameters (ExpValProb) \n"); goto TERMINATE; } } time_start = DDSIP_GetCpuTime (); mipstatus = CPXmipopt (DDSIP_env, DDSIP_lp); // Reset cplex parameters if (DDSIP_param->cpxnoeev) { status = DDSIP_SetCpxPara (DDSIP_param->cpxno, DDSIP_param->cpxisdbl, DDSIP_param->cpxwhich, DDSIP_param->cpxwhat); if (status) { fprintf (stderr, "ERROR: Failed to reset CPLEX parameters (ExpValProb) \n"); goto TERMINATE; } } if (DDSIP_Error (mipstatus)) { fprintf (stderr, "ERROR: Failed to optimize EXP\n"); status = mipstatus; goto TERMINATE; } // Error ? (blatant infeasible, scenario problem limit) if (DDSIP_Infeasible (mipstatus)) { status = 1; goto TERMINATE; } // No solution found ? (integer infeasible, some limit (node, time)) mipstatus = CPXgetstat (DDSIP_env, DDSIP_lp); if (DDSIP_NoSolution (mipstatus)) { status = 1; goto TERMINATE; } status = CPXgetx (DDSIP_env, DDSIP_lp, mipx, 0, DDSIP_bb->firstvar + DDSIP_bb->secvar - 1); if (status) { fprintf (stderr, "ERROR: Failed to get solution \n"); goto TERMINATE; } // output of result if (DDSIP_param->outlev) { status = CPXgetobjval (DDSIP_env, DDSIP_lp, &objval); if (status) { fprintf (stderr, "ERROR*: Failed to get best objective value \n"); fprintf (DDSIP_outfile, "ERROR*: Failed to get best objective value \n"); if (DDSIP_param->outlev) fprintf (DDSIP_bb->moreoutfile, "ERROR*: Failed to get best objective value \n"); goto TERMINATE; } if (mipstatus == CPXMIP_OPTIMAL) { bobjval = objval; } else { status = CPXgetbestobjval (DDSIP_env, DDSIP_lp, &bobjval); if (status) { fprintf (stderr, "ERROR: Failed to get value of best remaining node\n"); fprintf (DDSIP_outfile, "ERROR: Failed to get value of best remaining node\n"); if (DDSIP_param->outlev) fprintf (DDSIP_bb->moreoutfile, "ERROR: Failed to get value of best remaining node\n"); goto TERMINATE; } } gap = 100.0*(objval-bobjval)/(fabs(objval)+1e-4); nodes_1st = CPXgetnodecnt (DDSIP_env,DDSIP_lp); time_end = DDSIP_GetCpuTime (); time_start = time_end-time_start; time (&DDSIP_bb->cur_time); DDSIP_translate_time (difftime(DDSIP_bb->cur_time,DDSIP_bb->start_time),&wall_hrs,&wall_mins,&wall_secs); DDSIP_translate_time (time_end,&cpu_hrs,&cpu_mins,&cpu_secs); if (mipstatus == CPXMIP_OPTIMAL) fprintf (DDSIP_bb->moreoutfile, " exp. val. prob: Best=%-20.14g\tBound=%-20.14g (%9.4g%%) \t %3dh %02d:%02.0f / %3dh %02d:%05.2f (%6.2fs n: %4d)", objval, bobjval, gap, wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs, time_start, nodes_1st); else if (mipstatus == CPXMIP_OPTIMAL_TOL) fprintf (DDSIP_bb->moreoutfile, " exp. val. prob: Best=%-20.14g\tBound=%-20.14g (%9.4g%%) tol.\t %3dh %02d:%02.0f / %3dh %02d:%05.2f (%6.2fs n: %4d)", objval, bobjval, gap, wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs, time_start, nodes_1st); else if (mipstatus == CPXMIP_TIME_LIM_FEAS) fprintf (DDSIP_bb->moreoutfile, " exp. val. prob: Best=%-20.14g\tBound=%-20.14g (%9.4g%%) TIME\t %3dh %02d:%02.0f / %3dh %02d:%05.2f (%6.2fs n: %4d)", objval, bobjval, gap, wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs, time_start, nodes_1st); else fprintf (DDSIP_bb->moreoutfile, " exp. val. prob: Best=%-20.14g\tBound=%-20.14g (%9.4g%%) %-4d\t %3dh %02d:%02.0f / %3dh %02d:%05.2f (%6.2fs n: %4d)", objval, bobjval, gap, mipstatus, wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs, time_start, nodes_1st); } // Returns sometimes rubbish, don't know why.. if (!DDSIP_bb->adv_sol) DDSIP_bb->adv_sol = (double *) DDSIP_Alloc (sizeof (double), DDSIP_bb->firstvar, "DDSIP_bb->adv_sol(sipread)"); for (j = 0; j < DDSIP_bb->firstvar; j++) { // Numerical errors ? if (DDSIP_Equal (mipx[DDSIP_bb->firstindex[j]], 0.0)) mipx[DDSIP_bb->firstindex[j]] = 0.0; DDSIP_bb->adv_sol[j] = mipx[DDSIP_bb->firstindex[j]]; } TERMINATE: DDSIP_Free ((void **) &(mipx)); 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; }
//========================================================================== int main (int argc, char * argv[]) { // Temporary variables struct stat filestat; char astring[DDSIP_ln_fname]; int status = 0, cont, boundstat, comb, i; // guarantee minimal stacksize limit const rlim_t kStackSize = 128 * 1024 * 1024; // min stack size = 128 MB struct rlimit rl; int result; unsigned long cur_limit; result = getrlimit(RLIMIT_STACK, &rl); if (result == 0) { cur_limit = rl.rlim_cur; printf ("original stacksize limit %lu\n", cur_limit); if (rl.rlim_cur < kStackSize) { rl.rlim_cur = kStackSize; result = setrlimit(RLIMIT_STACK, &rl); if (result != 0) { fprintf(stderr, "setrlimit returned result = %d\n", result); } result = getrlimit(RLIMIT_STACK, &rl); if (result == 0) { cur_limit = rl.rlim_cur; printf ("changed stacksize limit %lu\n", cur_limit); } } } i = argc; // // Welcome printf ("#######################################################################################\n"); printf ("######### D D S I P -- Dual Decomposition In Stochastic Integer Programming #########\n"); printf ("######### %-66s #########\n", DDSIP_version); printf ("For copyright, license agreements, help, comments, requests, ... "); printf ("see\n\thttp://www.uni-duisburg-essen.de/~hn215go/ddsip.shtml\n"); printf ("\thttp://www.www.github.com/RalfGollmer/ddsip\n"); /* printf (" Copyright (C) to University of Duisburg-Essen \n\n"); */ /* printf(" This program is free software; you can redistribute it and/or\n"); */ /* printf (" modify it under the terms of the GNU General Public License\n"); */ /* printf(" as published by the Free Software Foundation; either version 2\n"); */ /* printf (" of the License, or (at your option) any later version.\n\n"); */ /* printf (" This program is distributed in the hope that it will be useful,\n"); */ /* printf(" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); */ /* printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); */ /* printf (" GNU General Public License for more details.\n\n"); */ /* printf (" You should have received a copy of the GNU General Public License\n"); */ /* printf(" along with this program; if not, write to the Free Software\n"); */ /* printf (" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"); */ /* printf ("==============================================================================\n\n"); */ // These four structures shall carry the whole problem data DDSIP_param = NULL; DDSIP_bb = NULL; DDSIP_data = NULL; DDSIP_node = NULL; // In DDSIP some signals are handled seperatly DDSIP_RegisterSignalHandlers (); // Create output directory if it doesn't already exist if (stat (DDSIP_outdir, &filestat) == -1) { sprintf (astring, "mkdir %s\n", DDSIP_outdir); i = system (astring); printf ("Creating subdirectory %s ...\n", DDSIP_outdir); } // remove possibly existing output file sprintf (astring, "rm -f %s\n", DDSIP_outfname); i = system (astring); // Open output file if ((DDSIP_outfile = fopen (DDSIP_outfname, "a")) == NULL) { fprintf (stderr, "ERROR: Cannot open '%s'. \n", DDSIP_outfname); status = 107; goto TERMINATE; } setbuf (DDSIP_outfile, 0); fprintf (DDSIP_outfile, "%s\n", argv[0]); fprintf (DDSIP_outfile, "-----------------------------------------------------------\n"); fprintf (DDSIP_outfile, "current system time: "); fflush (DDSIP_outfile); #ifndef _WIN32 i = system ("date"); // Print time to output file sprintf (astring, "date >> %s\n", DDSIP_outfname); i = system (astring); fprintf (DDSIP_outfile, "host : "); sprintf (astring, "hostname >> %s; cat /proc/cpuinfo | sed '/processor.*: 0/,/^$/!d' |grep -E 'vendor|cpu |model|stepping|MHz|cache |cores' >> %s\n", DDSIP_outfname, DDSIP_outfname); for (i = 0; i < 100; i++) exp(1.11*(-i-2)); i = system (astring); #else sprintf (astring, "date /T >> %s & time /T >> %s\n", DDSIP_outfname,DDSIP_outfname); i = system (astring); #endif fprintf (DDSIP_outfile, "\nDDSIP %s\n", DDSIP_version); fprintf (DDSIP_outfile, "-----------------------------------------------------------\n"); // Open cplex environment DDSIP_env = CPXopenCPLEX (&status); if (DDSIP_env == NULL) { fprintf (stderr, "ERROR: Failed to open cplex environment, CPLEX error code %d.\n",status); fprintf (DDSIP_outfile, "ERROR: Failed to open cplex environment, CPLEX error code %d.\n",status); return status; } sprintf (astring, "%s", CPXversion (DDSIP_env)); printf ("CPLEX version is %s\n", astring); fprintf (DDSIP_outfile, "CPLEX version is %s\n\n", astring); // Allocate the structures to hold the information on the problem DDSIP_param = (para_t *) DDSIP_Alloc (sizeof (para_t), 1, "param(Main)"); DDSIP_bb = (bb_t *) DDSIP_Alloc (sizeof (bb_t), 1, "bb(Main)"); DDSIP_data = (data_t *) DDSIP_Alloc (sizeof (data_t), 1, "data(Main)"); // Read model (lp) file if ((status = DDSIP_ReadModel ())) goto TERMINATE; // Read specification file if ((status = DDSIP_ReadSpec ())) goto TERMINATE; // Set specified CPLEX parameters if ((status = DDSIP_InitCpxPara ())) goto TERMINATE; // if a Benders annotation file is given, read it if (DDSIP_param->annotationFile) { status = CPXreadcopyannotations (DDSIP_env, DDSIP_lp, DDSIP_param->annotationFile); if ( status ) { fprintf (stderr, "ERROR: Failed to read and copy the annotation data from file %s.\n", DDSIP_param->annotationFile); fprintf (DDSIP_outfile, "ERROR: Failed to read and copy the annotation data from file %s.\n", DDSIP_param->annotationFile); goto TERMINATE; } } // data->cost contains: stoch. costs for all scenarios, followed by the original costs DDSIP_data->cost = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios * DDSIP_param->stoccost + DDSIP_data->novar, "cost (ReadData)"); // Store original objective coefficients status = CPXgetobj (DDSIP_env, DDSIP_lp, DDSIP_data->cost + DDSIP_param->scenarios * DDSIP_param->stoccost, 0, DDSIP_data->novar - 1); if (status) { fprintf (stderr, "ERROR: Failed to get objective coefficients\n"); fprintf (DDSIP_outfile, "ERROR: Failed to get objective coefficients\n"); goto TERMINATE; } DDSIP_bb->moreoutfile = NULL; if (DDSIP_param->outlev) { // Open debug output file if ((DDSIP_bb->moreoutfile = fopen (DDSIP_moreoutfname, "a")) == NULL) { fprintf (stderr, "ERROR: Cannot open '%s'. \n", DDSIP_moreoutfname); fprintf (DDSIP_outfile, "ERROR: Cannot open '%s'. \n", DDSIP_moreoutfname); status = 109; goto TERMINATE; } if (DDSIP_param->outlev > 10) { // Buffer size = 0 setbuf (stdout, 0); if (DDSIP_param->outlev > 20) setbuf (DDSIP_bb->moreoutfile, 0); } #ifndef _WIN32 // Print time to output file sprintf (astring, "date > %s\n", DDSIP_moreoutfname); i = system (astring); #else sprintf (astring, "date /T > %s & time /T >> %s\n", DDSIP_moreoutfname,DDSIP_moreoutfname); i = system (astring); #endif fprintf (DDSIP_bb->moreoutfile, "--------------------------------------------------------------"); fprintf (DDSIP_bb->moreoutfile, "---------\nThis is an additional output file of DDSIP. The "); fprintf (DDSIP_bb->moreoutfile, "actual amount of output\nis controlled by the parameter "); fprintf (DDSIP_bb->moreoutfile, "OUTLEV in the specification file.\n---------"); fprintf (DDSIP_bb->moreoutfile, "--------------------------------------------------------------\n\n"); } DDSIP_node = (node_t **) DDSIP_Alloc (sizeof (node_t *), DDSIP_param->nodelim + 3, "node(Main)"); DDSIP_node[0] = (node_t *) DDSIP_Alloc (sizeof (node_t), 1, "node[0](Main)"); DDSIP_node[0]->first_sol = (double **) DDSIP_Alloc (sizeof (double *), DDSIP_param->scenarios, "node[0]->first_sol(Main)"); DDSIP_node[0]->cursubsol = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->cursubsol(Main)"); DDSIP_node[0]->subbound = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->subbound(Main)"); if (DDSIP_param->cb) { DDSIP_node[0]->scenBoundsNoLag = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->scenBoundsNoLag(Main)"); DDSIP_node[0]->BoundNoLag = -DDSIP_infty; } DDSIP_node[0]->mipstatus = (int *) DDSIP_Alloc (sizeof (int), DDSIP_param->scenarios, "node[0]->mipstatus(Main)"); DDSIP_node[0]->ref_scenobj = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->ref_scenobj(Main)"); // Prepare first and second stage variables if ((status = DDSIP_InitStages ())) { fprintf (stderr, "ERROR: Failed to initialize stages\n"); fprintf (DDSIP_outfile, "ERROR: Failed to initialize stages\n"); goto TERMINATE; } // Read data file(s) if ((status = DDSIP_ReadData ())) goto TERMINATE; // Read order file if specified if (DDSIP_param->cpxorder) { status = CPXsetintparam (DDSIP_env, CPX_PARAM_MIPORDIND, 1); if (status) { fprintf (stderr, "ERROR: Failed to set cplex parameter CPX_PARAM_MIPORDIND.\n"); return status; } if (DDSIP_ReadCPLEXOrder ()) goto TERMINATE; } // Detect first and second stage constraints if ((status = DDSIP_DetectStageRows ())) { fprintf (stderr, "ERROR: Failed detection of row stages (BbInit)\n"); fprintf (DDSIP_outfile, "ERROR: Failed detection of row stages (BbInit)\n"); goto TERMINATE; } DDSIP_bb->DDSIP_step = solve; #ifdef CONIC_BUNDLE if (DDSIP_param->cb) { status = DDSIP_NonAnt (); if (status) goto TERMINATE; } #endif if (DDSIP_param->outlev) { printf ("\t Total initialization time: %4.2f seconds.\n", DDSIP_GetCpuTime ()); fprintf (DDSIP_bb->moreoutfile, " Total initialization time: %4.2f seconds.\n", DDSIP_GetCpuTime ()); } #ifndef _WIN32 sprintf (astring, "grep 'MHz' /proc/cpuinfo|sort -r|head -1 >> %s\n", DDSIP_outfname); i = system (astring); #endif // at the start there is no solution status = CPXsetintparam (DDSIP_env, CPX_PARAM_ADVIND, 0); if (status) { fprintf (stderr, "ERROR: Failed to set cplex parameter CPX_PARAM_ADVIND.\n"); fprintf (DDSIP_outfile, "ERROR: Failed to set cplex parameter CPX_PARAM_ADVIND.\n"); return status; } #ifndef NEOS // Write deterministic equivalent (only expectation-based cases) if (DDSIP_param->write_detequ) DDSIP_DetEqu (); #endif if (DDSIP_param->riskmod < 0) { fprintf (stderr, " pure risk models are disabled for now, exiting.\n"); fprintf (DDSIP_outfile, " pure risk models are disabled for now, exiting.\n"); goto TERMINATE; } if (DDSIP_param->stoccost && DDSIP_param->riskmod) { fprintf (DDSIP_outfile, "XXX Error: Risk optimization not implemented for stochastic cost coefficients.\n"); fprintf (stderr, "XXX Error: Risk optimization not implemented for stochastic cost coefficients.\n"); goto TERMINATE; } // Read advanced starting info if (DDSIP_param->advstart) { DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = adv; if ((status = DDSIP_AdvStart ())) goto TERMINATE; // Solution provided? if (DDSIP_param->advstart == 2) { DDSIP_bb->curnode = 0; DDSIP_bb->sug[DDSIP_param->nodelim + 2] = (struct sug_l *)DDSIP_Alloc (sizeof (sug_t), 1, "sug[0](Advanced start solution)"); (DDSIP_bb->sug[DDSIP_param->nodelim + 2])->firstval = (double *) DDSIP_Alloc (sizeof (double), DDSIP_bb->firstvar, "sug[0]->firstval(adv start)"); for (i = 0; i < (DDSIP_bb->firstvar); i++) (DDSIP_bb->sug[DDSIP_param->nodelim + 2]->firstval)[i] = DDSIP_bb->adv_sol[i]; (DDSIP_bb->sug[DDSIP_param->nodelim + 2])->next = NULL; if ((status = DDSIP_UpperBound (DDSIP_param->scenarios, 0)) && status < 100000) goto TERMINATE; } // Only weak consistency check: if ((DDSIP_node[0]->bound) > DDSIP_bb->bestvalue) { status = 121; goto TERMINATE; } fprintf (DDSIP_outfile, "-----------------------------------------------------------\n\n"); } // Solve EV and EEV if specified if (DDSIP_param->expected) { DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = eev; // status = 1 -> ExpValProb infeasible if ((status = DDSIP_ExpValProb ()) == 1) { if (DDSIP_param->outlev) fprintf (DDSIP_bb->moreoutfile, " exp. val. prob: INFEASIBLE\n"); fprintf (DDSIP_outfile, " exp. val. prob: INFEASIBLE\n"); } if (!status) { DDSIP_bb->curnode = 0; DDSIP_bb->sug[DDSIP_param->nodelim + 2] = (struct sug_l *)DDSIP_Alloc (sizeof (sug_t), 1, "sug[0](Advanced start solution)"); DDSIP_bb->sug[DDSIP_param->nodelim + 2]->firstval = (double *) DDSIP_Alloc (sizeof (double), DDSIP_bb->firstvar, "sug[i]->firstval(Heuristic)"); for (i = 0; i < DDSIP_bb->firstvar; i++) (DDSIP_bb->sug[DDSIP_param->nodelim + 2]->firstval)[i] = DDSIP_bb->adv_sol[i]; DDSIP_bb->sug[DDSIP_param->nodelim + 2]->next = NULL; if ((status = DDSIP_UpperBound (DDSIP_param->scenarios, 0)) && status < 100000) goto TERMINATE; } if (fabs (DDSIP_bb->expbest) < DDSIP_infty) { if (DDSIP_param->outlev) printf ("\t\t EEV: %13.7f\n", DDSIP_bb->expbest); fprintf (DDSIP_outfile, "-EEV: %13.7f\n", DDSIP_bb->expbest); } else { if (DDSIP_param->outlev) printf ("\t\t EEV: No solution found.\n"); fprintf (DDSIP_outfile, "-EEV: No solution found.\n"); } } // END if (EV) // stop here if NODELIM is zero if (!(DDSIP_param->nodelim)) goto TERMINATE; // Print cplex log to debugfile if (DDSIP_param->outlev > 51) { #ifdef CPLEX_12_8 if ((status = CPXsetlogfilename (DDSIP_env, DDSIP_moreoutfname, "a"))) goto TERMINATE; #else if ((status = CPXsetlogfile (DDSIP_env, DDSIP_bb->moreoutfile))) goto TERMINATE; #endif } // No of DDSIP iterations DDSIP_bb->noiter = 0; // cont = 1 if no stop criteria is fullfilled cont = 1; // comb tells in case of a combined heuristic, which one to apply (3 = RoundNear) comb = 3; if (DDSIP_param->outlev) printf ("Starting branch-and-bound algorithm.\n"); fprintf (DDSIP_outfile, "----------------------------------------------------------------------------------------\n"); while (cont) { // the cuts from the root node are contained in every following node model, there is no need to check their violation // for the scenario solutions. But the rounding heuristics could violate a cut, so keep them. #ifdef CONIC_BUNDLE #ifdef DEBUG //////////////////////////////////////////// if (DDSIP_bb->curnode && DDSIP_param->outlev) { if((DDSIP_node[DDSIP_bb->curnode-1])->step == dual) fprintf(DDSIP_bb->moreoutfile, "######## last node %d step=dual, leaf= %d, dualdescitcnt = %d, DDSIP_bb->cutoff= %d\n",DDSIP_bb->curnode-1,(DDSIP_node[DDSIP_bb->curnode-1])->leaf,DDSIP_bb->dualdescitcnt,DDSIP_bb->cutoff); } //////////////////////////////////////////// #endif if (DDSIP_param->outlev > 20 && DDSIP_bb->curnode && DDSIP_node[DDSIP_node[DDSIP_bb->curnode]->father]->cbReturn32) fprintf (DDSIP_bb->moreoutfile, "########## DDSIP_node[%d >father]->cbReturn32 = 1\n", DDSIP_bb->curnode); // Dual method if ((!DDSIP_bb->curnode || !DDSIP_node[DDSIP_node[DDSIP_bb->curnode]->father]->cbReturn32) && ((DDSIP_param->cb > 0 && (!(DDSIP_bb->noiter % abs(DDSIP_param->cb))) && (abs(DDSIP_param->riskmod) != 4 || DDSIP_bb->noiter)) || (DDSIP_param->cb < 0 && (((DDSIP_node[DDSIP_bb->curnode]->depth <= DDSIP_param->cb_depth) && abs(DDSIP_param->riskmod) != 4) || (abs(DDSIP_param->riskmod) == 5 && DDSIP_node[DDSIP_bb->curnode]->depth == 8) || (DDSIP_bb->noiter > DDSIP_param->cbBreakIters && ((!(DDSIP_bb->noiter % abs(DDSIP_param->cb))) || (!((DDSIP_bb->noiter+1) % -DDSIP_param->cb)) || (DDSIP_bb->noiter%200 > 199 - DDSIP_param->cbContinuous) || (DDSIP_bb->noiter < DDSIP_param->cbContinuous + DDSIP_param->cbBreakIters) || ((DDSIP_bb->noiter >= 2*DDSIP_param->cbBreakIters) && (DDSIP_bb->noiter < DDSIP_param->cbContinuous + 2*DDSIP_param->cbBreakIters)) || ((DDSIP_bb->cutoff > 6) && (((DDSIP_bb->no_reduced_front < 51) && (DDSIP_bb->noiter % -DDSIP_param->cb) < DDSIP_param->cbContinuous) || (((DDSIP_node[DDSIP_bb->curnode-1])->step == dual) && (DDSIP_node[DDSIP_bb->curnode-1])->leaf /*&& (DDSIP_bb->dualdescitcnt < 11)*/) ) ) ) ) || (abs(DDSIP_param->riskmod) != 5 && DDSIP_bb->noiter <= DDSIP_param->cbBreakIters && DDSIP_bb->noiter > DDSIP_param->cbBreakIters*.5 && (CBFORALL || (DDSIP_node[DDSIP_bb->curnode]->numInheritedSols > (DDSIP_Imin(DDSIP_param->scenarios/20,2)+(DDSIP_param->scenarios+1)/2)))) ) ) ) ) { DDSIP_bb->DDSIP_step = DDSIP_node[DDSIP_bb->curnode]->step = dual; if ((status = DDSIP_DualOpt ())) { if (!DDSIP_bb->curnode) goto TERMINATE; else { DDSIP_bb->skip = 1; DDSIP_node[DDSIP_bb->curnode]->bound = DDSIP_infty; } } } else { DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = solve; // status=1 means there was no solution found to a scenario problem if ((status = DDSIP_LowerBound ())) goto TERMINATE; } #else DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = solve; // status=1 means there was no solution found to a subproblem if ((status = LowerBound ())) goto TERMINATE; #endif if (!DDSIP_bb->skip || DDSIP_bb->skip == -1) { double old_bound; int cntr, maxCntr; DDSIP_bb->cutAdded = 0; DDSIP_EvaluateScenarioSolutions (&comb); cntr = 0; if (DDSIP_node[DDSIP_bb->curnode]->step != dual) maxCntr = DDSIP_param->numberReinits; else maxCntr = 0; old_bound = DDSIP_node[DDSIP_bb->curnode]->bound; boundstat = DDSIP_Bound (); if (!DDSIP_bb->curnode) { int cnt, j; double lhs; cutpool_t *currentCut; DDSIP_PrintState (DDSIP_bb->noiter); if (DDSIP_bb->cutAdded && DDSIP_param->outlev) { fprintf (DDSIP_outfile, " %6d%101d cuts\n", DDSIP_bb->curnode, DDSIP_bb->cutAdded); } while ((DDSIP_bb->cutAdded || DDSIP_node[0]->step == dual) && cntr < maxCntr) { old_bound = DDSIP_node[0]->bound; // Free the solutions from former LowerBound for (i = 0; i < DDSIP_param->scenarios; i++) { if (((DDSIP_node[0])->first_sol)[i]) { if (DDSIP_node[0]->step == solve) { currentCut = DDSIP_bb->cutpool; while (currentCut) { lhs = 0.; for (j = 0; j < DDSIP_bb->firstvar; j++) { lhs += (DDSIP_node[0])->first_sol[i][j] * currentCut->matval[j]; } if (lhs < currentCut->rhs - 1.e-7) { #ifdef DEBUG if (DDSIP_param->outlev > 50) fprintf (DDSIP_bb->moreoutfile, "scen %d solution violates cut %d.\n", i+1, currentCut->number); #endif if ((cnt = (int) ((((DDSIP_node[0])->first_sol)[i])[DDSIP_bb->firstvar] - 0.9))) for (j = i + 1; cnt && j < DDSIP_param->scenarios; j++) { { if (((DDSIP_node[0])->first_sol)[j] && ((DDSIP_node[0])->first_sol)[i] == ((DDSIP_node[0])->first_sol)[j]) { ((DDSIP_node[0])->first_sol)[j] = NULL; cnt--; } } } DDSIP_Free ((void **) &(((DDSIP_node[0])->first_sol)[i])); break; } currentCut = currentCut->prev; } } else { if ((cnt = (int) ((((DDSIP_node[0])->first_sol)[i])[DDSIP_bb->firstvar] - 0.9))) for (j = i + 1; cnt && j < DDSIP_param->scenarios; j++) { { if (((DDSIP_node[0])->first_sol)[j] && ((DDSIP_node[0])->first_sol)[i] == ((DDSIP_node[0])->first_sol)[j]) { ((DDSIP_node[0])->first_sol)[j] = NULL; cnt--; } } } DDSIP_Free ((void **) &(((DDSIP_node[0])->first_sol)[i])); } } } DDSIP_node[0]->step = DDSIP_bb->DDSIP_step = solve; // status=1 means there was no solution found to a scenario problem if ((status = DDSIP_LowerBound ())) goto TERMINATE; DDSIP_bb->cutAdded = 0; DDSIP_EvaluateScenarioSolutions (&comb); cntr++; DDSIP_bb->bestbound = DDSIP_node[0]->bound; DDSIP_bb->noiter++; DDSIP_PrintState (1); if (DDSIP_bb->cutAdded && DDSIP_param->outlev) { fprintf (DDSIP_outfile, " %6d %82d. reinit: %8d cuts\n", 0, cntr, DDSIP_bb->cutAdded); } if ((DDSIP_node[0]->bound - old_bound)/(fabs(old_bound) + 1e-16) < 1.e-7 || (DDSIP_bb->bestvalue - DDSIP_node[0]->bound)/(fabs(DDSIP_bb->bestvalue) + 1e-16) < 0.5*DDSIP_param->relgap) break; } if (DDSIP_param->deleteRedundantCuts) DDSIP_CheckRedundancy(1); } else { // Print a line of output at the first, the last and each `ith' node if (!DDSIP_bb->noiter || (!((DDSIP_bb->noiter + 1) % DDSIP_param->logfreq)) || (DDSIP_param->outlev && (DDSIP_node[DDSIP_bb->curnode])->step == dual)) DDSIP_PrintState (DDSIP_bb->noiter); if (DDSIP_bb->cutAdded && DDSIP_param->outlev > 1) { fprintf (DDSIP_outfile, " %6d%101d cuts\n", DDSIP_bb->curnode, DDSIP_bb->cutAdded); } } } else { boundstat = DDSIP_Bound (); // Print a line of output at the first, the last and each `ith' node if (!DDSIP_bb->noiter || (!((DDSIP_bb->noiter + 1) % DDSIP_param->logfreq)) || (DDSIP_param->outlev && (DDSIP_node[DDSIP_bb->curnode])->step == dual)) DDSIP_PrintState (DDSIP_bb->noiter); } if (!DDSIP_bb->curnode) DDSIP_bb->cutCntr0 = DDSIP_bb->cutNumber; else if (DDSIP_param->alwaysBendersCuts) { if (DDSIP_bb->curnode == 24) { if (DDSIP_bb->cutCntr0 == DDSIP_bb->cutNumber) { if (DDSIP_param->outlev > 20) fprintf (DDSIP_bb->moreoutfile, "### setting alwaysBendersCuts to 0\n"); DDSIP_param->alwaysBendersCuts = 0; } else DDSIP_bb->cutCntr0 = DDSIP_bb->cutNumber; } else if (DDSIP_bb->curnode == 49) { if (DDSIP_bb->cutCntr0 == DDSIP_bb->cutNumber) { if (DDSIP_param->outlev > 20) fprintf (DDSIP_bb->moreoutfile, "### setting alwaysBendersCuts to 0\n"); DDSIP_param->alwaysBendersCuts = 0; } else DDSIP_bb->cutCntr0 = DDSIP_bb->cutNumber; } else if (DDSIP_bb->curnode == 99) { if (DDSIP_bb->cutCntr0 == DDSIP_bb->cutNumber) { if (DDSIP_param->outlev > 20) fprintf (DDSIP_bb->moreoutfile, "### setting alwaysBendersCuts to 0\n"); DDSIP_param->alwaysBendersCuts = 0; } } } // DDSIP_bb->skip > 0 indicates that UpperBound calls have been skipped // DDSIP_bb->heurval contains the objective value of the heuristic solution // Reset to initial values DDSIP_bb->heurval = DDSIP_infty; DDSIP_bb->skip = 0; cont = DDSIP_Continue (&DDSIP_bb->noiter, &boundstat); if (!cont) { status = boundstat; goto TERMINATE; } if ((status = DDSIP_Branch ())) goto TERMINATE; if (DDSIP_param->deleteRedundantCuts && !(DDSIP_bb->curnode % 10)) DDSIP_CheckRedundancy(1); } // Termination TERMINATE: DDSIP_PrintErrorMsg (status); printf ("\nOutput files in directory `%s'.\n", DDSIP_outdir); // Free up problem as allocated above // if (DDSIP_node != NULL) { DDSIP_FreeFrontNodes (); for (i = 0; i < DDSIP_bb->nonode; i++) DDSIP_Free ((void **) &(DDSIP_node[i])); DDSIP_Free ((void **) &(DDSIP_node)); } if (DDSIP_data != NULL) { DDSIP_FreeData (); DDSIP_Free ((void **) &(DDSIP_data)); } // Free up the problem as allocated by CPXcreateprob, if necessary if (DDSIP_lp != NULL) { status = CPXfreeprob (DDSIP_env, &DDSIP_lp); if (status) fprintf (stderr, "ERROR: CPXfreeprob failed, error code %d\n", status); } // Free up the CPLEX environment if (DDSIP_env != NULL) { status = CPXcloseCPLEX (&DDSIP_env); if (status) { char errmsg[1024]; fprintf (stderr, "ERROR: Failed to close CPLEX environment.\n"); CPXgeterrorstring (DDSIP_env, status, errmsg); fprintf (stderr, "%s\n", errmsg); } } if (DDSIP_bb != NULL) { DDSIP_FreeBb (); DDSIP_Free ((void **) &(DDSIP_bb)); } if (DDSIP_param->outlev) printf ("Terminating DDSIP.\n"); if (DDSIP_param != NULL) { DDSIP_FreeParam (); DDSIP_Free ((void **) &(DDSIP_param)); } fprintf (DDSIP_outfile, "Current system time: "); #ifndef _WIN32 i = system ("date"); // Print time to output file sprintf (astring, "date >> %s\n", DDSIP_outfname); i = system (astring); #else sprintf (astring, "date /T >> %s & time /T >> %s\n", DDSIP_outfname,DDSIP_outfname); i = system (astring); #endif if (DDSIP_outfile != NULL) fclose (DDSIP_outfile); return 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; }