void colgen_change_arc_capacities (colgen_t* colgenp, int* arc_open) // modifies right-hand side of current master problem according to values in arc_open { int i; int nchangec = 0; // amount of open arcs which we closed int nchangeo = 0; // amount of closed arcs which we opened // close open arcs for (i = 0; i < colgenp->instp->n_arcs; i++) { if (!arc_open[i] && colgenp->arc_cap[i] > 0.0) { colgenp->col_val[nchangec] = colgenp->arc_cap[i] = 0.0; colgenp->col_ind[nchangec++] = i; } } if (nchangec) { // assume the solution to be infeasible if (colgenp->overflow == 0) colgenp->overflow = 1; // update right-hand sides of affected capacity constraints and reoptimize GRB(setdblattrlist(colgenp->lp, GRB_DBL_ATTR_RHS, nchangec, colgenp->col_ind, colgenp->col_val)); GRB(updatemodel(colgenp->lp)); GRB(setintparam(env, GRB_INT_PAR_METHOD, 1)); GRB(optimize(colgenp->lp)); GRB(getintattr(colgenp->lp, GRB_INT_ATTR_STATUS, &grb_status)); assert(grb_status == GRB_OPTIMAL); } // open closed arcs for (i = 0; i < colgenp->instp->n_arcs; i++) { if (arc_open[i] && colgenp->arc_cap[i] == 0.0) { colgenp->col_val[nchangeo] = colgenp->arc_cap[i] = colgenp->instp->arc_capacity[i]; colgenp->col_ind[nchangeo++] = i; } } if (nchangeo) { // update right-hand sides of affected capacity constraints and reoptimize GRB(setdblattrlist(colgenp->lp, GRB_DBL_ATTR_RHS, nchangeo, colgenp->col_ind, colgenp->col_val)); GRB(updatemodel(colgenp->lp)); GRB(setintparam(env, GRB_INT_PAR_METHOD, 0)); GRB(optimize(colgenp->lp)); GRB(getintattr(colgenp->lp, GRB_INT_ATTR_STATUS, &grb_status)); assert(grb_status == GRB_OPTIMAL); } if (nchangec || nchangeo) { // if any change was made // undo changes to col_val for (i = 0; i <= nchangec || i <= nchangeo; i++) colgenp->col_val[i] = 1.0; // retrieve simplex multipliers GRB(getdblattrarray(colgenp->lp, GRB_DBL_ATTR_PI, 0, colgenp->instp->n_arcs, colgenp->arc_mul)); GRB(getdblattrarray(colgenp->lp, GRB_DBL_ATTR_PI, colgenp->instp->n_arcs, colgenp->instp->n_commods, colgenp->commod_mul)); // retrieve artificial arc path flows GRB(getdblattrarray(colgenp->lp, GRB_DBL_ATTR_X, 0, colgenp->instp->n_commods, colgenp->path_flow)); // reset bounds colgenp->z_lb = 0.0; colgenp->z_ub = inf; } }
void colgen_trim (colgen_t* colgenp) // removes all columns from the master problem except those corresponding to the artificial arc paths { int i; // assume infeasibility colgenp->overflow = 1; // delete the added columns for (i = colgenp->instp->n_commods; i < colgenp->n_paths; i++) GRB(delvars(colgenp->lp, 1, &i)); GRB(updatemodel(colgenp->lp)); colgenp->n_paths = colgenp->instp->n_commods; // reoptimize GRB(setintparam(env, GRB_INT_PAR_METHOD, 1)); GRB(optimize(colgenp->lp)); GRB(getintattr(colgenp->lp, GRB_INT_ATTR_STATUS, &grb_status)); assert(grb_status == GRB_OPTIMAL); // retrieve simplex multipliers GRB(getdblattrarray(colgenp->lp, GRB_DBL_ATTR_PI, 0, colgenp->instp->n_arcs, colgenp->arc_mul)); GRB(getdblattrarray(colgenp->lp, GRB_DBL_ATTR_PI, colgenp->instp->n_arcs, colgenp->instp->n_commods, colgenp->commod_mul)); // retrieve artificial arc path flows GRB(getdblattrarray(colgenp->lp, GRB_DBL_ATTR_X, 0, colgenp->n_paths, colgenp->path_flow)); // reset bounds colgenp->z_lb = 0.0; colgenp->z_ub = inf; }
static PyObject * tkwin_getattr(PyObject * self, char * name) { PyObject * result; result = getintattr((TkWinObject*)self, name); if (result) return result; return Py_FindMethod(tkwin_methods, self, name); }
int colgen_iteration (colgen_t* colgenp) // performs one iteration of the column-generation algorithm { int i, k, flag; int newcols = 0; // solve the column pricing subproblem colgen_compute_shortest_paths(colgenp); // generate new columns with non-positive reduced costs for (k = 0; k < colgenp->instp->n_commods; k++) if (colgenp->graph[k].dist[colgenp->instp->commod_dest_node[k]] <= colgenp->commod_mul[k]) newcols += colgen_generate(colgenp, k); // compute the lower bound on the optimal objective value colgenp->z_lb = 0.0; for (i = 0; i < colgenp->instp->n_arcs; i++) colgenp->z_lb += colgenp->arc_mul[i] * colgenp->arc_cap[i]; for (k = 0; k < colgenp->instp->n_commods; k++) { colgenp->z_lb += colgenp->graph[k].dist[colgenp->instp->commod_dest_node[k]] * colgenp->instp->commod_supply[k]; } if (newcols > 0) { // reoptimize GRB(updatemodel(colgenp->lp)); GRB(setintparam(env, GRB_INT_PAR_METHOD, 0)); GRB(optimize(colgenp->lp)); GRB(getintattr(colgenp->lp, GRB_INT_ATTR_STATUS, &grb_status)); assert(grb_status == GRB_OPTIMAL); // retrieve simplex multipliers GRB(getdblattrarray(colgenp->lp, GRB_DBL_ATTR_PI, 0, colgenp->instp->n_arcs, colgenp->arc_mul)); GRB(getdblattrarray(colgenp->lp, GRB_DBL_ATTR_PI, colgenp->instp->n_arcs, colgenp->instp->n_commods, colgenp->commod_mul)); if (colgenp->overflow) { // retrieve artificial arc flow values GRB(getdblattrarray(colgenp->lp, GRB_DBL_ATTR_X, 0, colgenp->instp->n_commods, colgenp->path_flow)); flag = 1; for (k = 0; k < colgenp->instp->n_commods && flag; k++) if (colgenp->path_flow[k] > 0.0) flag = 0; // if all are zero, then the solution is primal-feasible if (flag) colgenp->overflow = 0; } } // retrieve the upper bound on the optimal objective value GRB(getdblattr(colgenp->lp, GRB_DBL_ATTR_OBJVAL, &colgenp->z_ub)); //printf("%.40f <= Z* <= %.40f\n", colgenp->z_lb, colgenp->z_ub); //fflush(stdout); return newcols; }
colgen_t colgen_create (cmnd_t* instp) { colgen_t colgen; int i, k; char* sense = (char*) (malloc((instp->n_commods + instp->n_arcs) * sizeof(char))); colgen.instp = instp; colgen.graph = (malloc(instp->n_commods * sizeof(simple_graph_t))); colgen.overflow = 1; colgen.n_paths = colgen.prev_alloc = colgen.current_alloc = instp->n_commods; colgen.arc_cap = (malloc((instp->n_arcs + instp->n_commods) * sizeof(double))); colgen.arc_mul = (malloc(instp->n_arcs * sizeof(double))); colgen.overflow_mul = (malloc(instp->n_commods* sizeof(double))); colgen.commod_mul = (malloc(instp->n_commods * sizeof(double))); colgen.col_val = (malloc((2 + instp->n_arcs) * sizeof(double))); colgen.col_ind = (malloc((2 + instp->n_arcs) * sizeof(int))); colgen.path_ucost = (malloc(instp->n_commods * sizeof(double))); colgen.path_flow = (malloc(instp->n_commods * sizeof(double))); colgen.path_commod = (malloc(instp->n_commods * sizeof(int))); colgen.arc_total_flow = (malloc(instp->n_arcs * sizeof(double))); colgen.arc_total_ucost = (malloc(instp->n_arcs * sizeof(double))); colgen.arc_open = (malloc(instp->n_arcs * sizeof(int))); colgen.best_arc_open = (malloc(instp->n_arcs * sizeof(int))); colgen.commod_arc_flow = (malloc(instp->n_commods * sizeof(double*))); colgen.path_arcs = (malloc(colgen.current_alloc * sizeof(char*))); colgen.commod_arc_lfactor = (malloc(instp->n_commods * sizeof(double*))); for (i = 0; i < instp->n_arcs; i++) { sense[i] = GRB_LESS_EQUAL; // sense of capacity constraints colgen.arc_cap[i] = instp->arc_capacity[i]; // initial right-hand sides of capacity constraints colgen.col_val[i] = 1.0; } colgen.col_val[instp->n_arcs] = 1.0; for (k = 0; k < instp->n_commods; k++) { colgen.commod_arc_lfactor[k] = (malloc(instp->n_arcs * sizeof(double))); for (i = 0; i < instp->n_arcs; i++) colgen.commod_arc_lfactor[k][i] = 0.0; // default linearization factors colgen.path_arcs[k] = (calloc(instp->n_arcs, sizeof(char))); sense[instp->n_arcs + k] = GRB_EQUAL; // sense of bundle constraints colgen.arc_cap[instp->n_arcs + k] = instp->commod_supply[k]; // right-hand sides of bundle constraints colgen.graph[k] = simple_graph_create(instp); // pricing graph creation colgen.commod_arc_flow[k] = (malloc(instp->n_arcs * sizeof(double))); } // master problem creation GRB(newmodel(env, &colgen.lp, "CMNF path-based formulation", 0, NULL, NULL, NULL, NULL, NULL)); // the first n_arcs constraints are the capacity constraints GRB(addconstrs(colgen.lp, instp->n_arcs, 0, NULL, NULL, NULL, sense, colgen.arc_cap, NULL)); // followed by n_commods bundle constraints GRB(addconstrs(colgen.lp, instp->n_commods, 0, NULL, NULL, NULL, &sense[instp->n_arcs], instp->commod_supply, NULL)); GRB(updatemodel(colgen.lp)); // overflow paths creation (paths containing only the artificial arc from source to sink for each commodity) for (k = 0; k < instp->n_commods; k++) { colgen.path_ucost[k] = instp->commod_overflow_ucost[k]; colgen.path_flow[k] = 0.0; colgen.path_commod[k] = k; colgen.col_ind[0] = instp->n_arcs + k; GRB(addvar(colgen.lp, 1, colgen.col_ind, colgen.col_val, colgen.path_ucost[k], 0.0, instp->commod_supply[k], GRB_CONTINUOUS, NULL)); } GRB(updatemodel(colgen.lp)); // solver parameter settings GRB(setintparam(env, GRB_INT_PAR_METHOD, 1)); // optimization GRB(optimize(colgen.lp)); GRB(getintattr(colgen.lp, GRB_INT_ATTR_STATUS, &grb_status)); assert(grb_status == GRB_OPTIMAL); // initial primal and dual values GRB(getdblattrarray(colgen.lp, GRB_DBL_ATTR_X, 0, colgen.n_paths, colgen.path_flow)); GRB(getdblattrarray(colgen.lp, GRB_DBL_ATTR_PI, 0, instp->n_arcs, colgen.arc_mul)); GRB(getdblattrarray(colgen.lp, GRB_DBL_ATTR_PI, instp->n_arcs, instp->n_commods, colgen.commod_mul)); // initial bounds on the optimal objective value colgen.z_lb = 0.0; colgen.z_ub = inf; return colgen; }