void NUMlinprog_run (NUMlinprog me) { try { glp_smcp parm; glp_init_smcp (& parm); parm. msg_lev = GLP_MSG_OFF; my status = glp_simplex (my linearProgram, & parm); switch (my status) { case GLP_EBADB: Melder_throw (U"Unable to start the search, because the initial basis is invalid."); case GLP_ESING: Melder_throw (U"Unable to start the search, because the basis matrix is singular."); case GLP_ECOND: Melder_throw (U"Unable to start the search, because the basis matrix is ill-conditioned."); case GLP_EBOUND: Melder_throw (U"Unable to start the search, because some variables have incorrect bounds."); case GLP_EFAIL: Melder_throw (U"Search prematurely terminated due to solver failure."); case GLP_EOBJLL: Melder_throw (U"Search prematurely terminated: lower limit reached."); case GLP_EOBJUL: Melder_throw (U"Search prematurely terminated: upper limit reached."); case GLP_EITLIM: Melder_throw (U"Search prematurely terminated: iteration limit exceeded."); case GLP_ETMLIM: Melder_throw (U"Search prematurely terminated: time limit exceeded."); case GLP_ENOPFS: Melder_throw (U"The problem has no primal feasible solution."); case GLP_ENODFS: Melder_throw (U"The problem has no dual feasible solution."); default: break; } my status = glp_get_status (my linearProgram); switch (my status) { case GLP_INFEAS: Melder_throw (U"Solution is infeasible."); case GLP_NOFEAS: Melder_throw (U"Problem has no feasible solution."); case GLP_UNBND: Melder_throw (U"Problem has unbounded solution."); case GLP_UNDEF: Melder_throw (U"Solution is undefined."); default: break; } if (my status == GLP_FEAS) { Melder_warning (U"Linear programming solution is feasible but not optimal."); } } catch (MelderError) { Melder_throw (U"Linear programming: not run."); } }
bool glpk_wrapper::is_solution_unbounded() { assert(is_sat()); if (solver_type == SIMPLEX || solver_type == EXACT) { int status = glp_get_status(lp); return status == GLP_UNBND; } else { return false; } }
static int solve_mip(glp_prob *P, const glp_iocp *parm) { /* solve MIP directly without using the preprocessor */ glp_tree *T; int ret; /* optimal basis to LP relaxation must be provided */ if (glp_get_status(P) != GLP_OPT) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_intopt: optimal basis to initial LP relaxation" " not provided\n"); ret = GLP_EROOT; goto done; } /* it seems all is ok */ if (parm->msg_lev >= GLP_MSG_ALL) xprintf("Integer optimization begins...\n"); /* create the branch-and-bound tree */ T = ios_create_tree(P, parm); /* solve the problem instance */ ret = ios_driver(T); /* delete the branch-and-bound tree */ ios_delete_tree(T); /* analyze exit code reported by the mip driver */ if (ret == 0) { if (P->mip_stat == GLP_FEAS) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("INTEGER OPTIMAL SOLUTION FOUND\n"); P->mip_stat = GLP_OPT; } else { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION\n"); P->mip_stat = GLP_NOFEAS; } } else if (ret == GLP_EMIPGAP) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("RELATIVE MIP GAP TOLERANCE REACHED; SEARCH TERMINA" "TED\n"); } else if (ret == GLP_ETMLIM) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); } else if (ret == GLP_EFAIL) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_intopt: cannot solve current LP relaxation\n"); } else if (ret == GLP_ESTOP) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("SEARCH TERMINATED BY APPLICATION\n"); } else xassert(ret != ret); done: return ret; }
int CMyProblem::PrintLPSolution(ostream &out) { glp_create_index(lp); out << "LP solution" << endl; out << "Dir;" << ((glp_get_obj_dir(lp)==GLP_MIN) ? "min" : "max") << endl; out << "f; " << glp_get_obj_val(lp) << ";/*" << RealResult() << "*/" << endl; out << "Status;" << DecodeStatus(glp_get_status(lp)) << endl; PrintSolArray(lp,"x",out); PrintSolArray(lp,"y",out); glp_delete_index(lp); return 0; }
/* call the LP solver; mult is either +1.0 or -1.0 */ static char *invoke_lp(void) {int glp_res; glp_res=glp_simplex(P,&parm); switch(glp_res){ case 0: glp_res=glp_get_status(P); break; case GLP_ENOPFS: // no primal feasible solution glp_res=GLP_NOFEAS; break; default: return glp_return_msg(glp_res); } return (glp_res==GLP_OPT ? EXPR_TRUE : glp_res==GLP_NOFEAS ? EXPR_FALSE : glp_status_msg(glp_res)); }
int lpx_get_status(glp_prob *lp) { /* retrieve generic status of basic solution */ int status; switch (glp_get_status(lp)) { case GLP_OPT: status = LPX_OPT; break; case GLP_FEAS: status = LPX_FEAS; break; case GLP_INFEAS: status = LPX_INFEAS; break; case GLP_NOFEAS: status = LPX_NOFEAS; break; case GLP_UNBND: status = LPX_UNBND; break; case GLP_UNDEF: status = LPX_UNDEF; break; default: xassert(lp != lp); } return status; }
static PyObject* LPX_getstatus(LPXObject *self, void *closure) { int status; switch (self->last_solver) { case -1: case 0: status=glp_get_status(LP); break; case 1: status=glp_ipt_status(LP); break; case 2: status=glp_mip_status(LP); break; default: PyErr_SetString(PyExc_RuntimeError, "bad internal state for last solver identifier"); return NULL; } return glpstatus2string(status); }
int glp_print_sol(glp_prob *P, const char *fname) { /* write basic solution in printable format */ glp_file *fp; GLPROW *row; GLPCOL *col; int i, j, t, ae_ind, re_ind, ret; double ae_max, re_max; xprintf("Writing basic solution to '%s'...\n", fname); fp = glp_open(fname, "w"); if (fp == NULL) { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); ret = 1; goto done; } xfprintf(fp, "%-12s%s\n", "Problem:", P->name == NULL ? "" : P->name); xfprintf(fp, "%-12s%d\n", "Rows:", P->m); xfprintf(fp, "%-12s%d\n", "Columns:", P->n); xfprintf(fp, "%-12s%d\n", "Non-zeros:", P->nnz); t = glp_get_status(P); xfprintf(fp, "%-12s%s\n", "Status:", t == GLP_OPT ? "OPTIMAL" : t == GLP_FEAS ? "FEASIBLE" : t == GLP_INFEAS ? "INFEASIBLE (INTERMEDIATE)" : t == GLP_NOFEAS ? "INFEASIBLE (FINAL)" : t == GLP_UNBND ? "UNBOUNDED" : t == GLP_UNDEF ? "UNDEFINED" : "???"); xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", P->obj == NULL ? "" : P->obj, P->obj == NULL ? "" : " = ", P->obj_val, P->dir == GLP_MIN ? "MINimum" : P->dir == GLP_MAX ? "MAXimum" : "???"); xfprintf(fp, "\n"); xfprintf(fp, " No. Row name St Activity Lower bound " " Upper bound Marginal\n"); xfprintf(fp, "------ ------------ -- ------------- ------------- " "------------- -------------\n"); for (i = 1; i <= P->m; i++) { row = P->row[i]; xfprintf(fp, "%6d ", i); if (row->name == NULL || strlen(row->name) <= 12) xfprintf(fp, "%-12s ", row->name == NULL ? "" : row->name); else xfprintf(fp, "%s\n%20s", row->name, ""); xfprintf(fp, "%s ", row->stat == GLP_BS ? "B " : row->stat == GLP_NL ? "NL" : row->stat == GLP_NU ? "NU" : row->stat == GLP_NF ? "NF" : row->stat == GLP_NS ? "NS" : "??"); xfprintf(fp, "%13.6g ", fabs(row->prim) <= 1e-9 ? 0.0 : row->prim); if (row->type == GLP_LO || row->type == GLP_DB || row->type == GLP_FX) xfprintf(fp, "%13.6g ", row->lb); else xfprintf(fp, "%13s ", ""); if (row->type == GLP_UP || row->type == GLP_DB) xfprintf(fp, "%13.6g ", row->ub); else xfprintf(fp, "%13s ", row->type == GLP_FX ? "=" : ""); if (row->stat != GLP_BS) { if (fabs(row->dual) <= 1e-9) xfprintf(fp, "%13s", "< eps"); else xfprintf(fp, "%13.6g ", row->dual); } xfprintf(fp, "\n"); } xfprintf(fp, "\n"); xfprintf(fp, " No. Column name St Activity Lower bound " " Upper bound Marginal\n"); xfprintf(fp, "------ ------------ -- ------------- ------------- " "------------- -------------\n"); for (j = 1; j <= P->n; j++) { col = P->col[j]; xfprintf(fp, "%6d ", j); if (col->name == NULL || strlen(col->name) <= 12) xfprintf(fp, "%-12s ", col->name == NULL ? "" : col->name); else xfprintf(fp, "%s\n%20s", col->name, ""); xfprintf(fp, "%s ", col->stat == GLP_BS ? "B " : col->stat == GLP_NL ? "NL" : col->stat == GLP_NU ? "NU" : col->stat == GLP_NF ? "NF" : col->stat == GLP_NS ? "NS" : "??"); xfprintf(fp, "%13.6g ", fabs(col->prim) <= 1e-9 ? 0.0 : col->prim); if (col->type == GLP_LO || col->type == GLP_DB || col->type == GLP_FX) xfprintf(fp, "%13.6g ", col->lb); else xfprintf(fp, "%13s ", ""); if (col->type == GLP_UP || col->type == GLP_DB) xfprintf(fp, "%13.6g ", col->ub); else xfprintf(fp, "%13s ", col->type == GLP_FX ? "=" : ""); if (col->stat != GLP_BS) { if (fabs(col->dual) <= 1e-9) xfprintf(fp, "%13s", "< eps"); else xfprintf(fp, "%13.6g ", col->dual); } xfprintf(fp, "\n"); } xfprintf(fp, "\n"); xfprintf(fp, "Karush-Kuhn-Tucker optimality conditions:\n"); xfprintf(fp, "\n"); glp_check_kkt(P, GLP_SOL, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, &re_ind); xfprintf(fp, "KKT.PE: max.abs.err = %.2e on row %d\n", ae_max, ae_ind); xfprintf(fp, " max.rel.err = %.2e on row %d\n", re_max, re_ind); xfprintf(fp, "%8s%s\n", "", re_max <= 1e-9 ? "High quality" : re_max <= 1e-6 ? "Medium quality" : re_max <= 1e-3 ? "Low quality" : "PRIMAL SOLUTION IS WRONG"); xfprintf(fp, "\n"); glp_check_kkt(P, GLP_SOL, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, &re_ind); xfprintf(fp, "KKT.PB: max.abs.err = %.2e on %s %d\n", ae_max, ae_ind <= P->m ? "row" : "column", ae_ind <= P->m ? ae_ind : ae_ind - P->m); xfprintf(fp, " max.rel.err = %.2e on %s %d\n", re_max, re_ind <= P->m ? "row" : "column", re_ind <= P->m ? re_ind : re_ind - P->m); xfprintf(fp, "%8s%s\n", "", re_max <= 1e-9 ? "High quality" : re_max <= 1e-6 ? "Medium quality" : re_max <= 1e-3 ? "Low quality" : "PRIMAL SOLUTION IS INFEASIBL" "E"); xfprintf(fp, "\n"); glp_check_kkt(P, GLP_SOL, GLP_KKT_DE, &ae_max, &ae_ind, &re_max, &re_ind); xfprintf(fp, "KKT.DE: max.abs.err = %.2e on column %d\n", ae_max, ae_ind == 0 ? 0 : ae_ind - P->m); xfprintf(fp, " max.rel.err = %.2e on column %d\n", re_max, re_ind == 0 ? 0 : re_ind - P->m); xfprintf(fp, "%8s%s\n", "", re_max <= 1e-9 ? "High quality" : re_max <= 1e-6 ? "Medium quality" : re_max <= 1e-3 ? "Low quality" : "DUAL SOLUTION IS WRONG"); xfprintf(fp, "\n"); glp_check_kkt(P, GLP_SOL, GLP_KKT_DB, &ae_max, &ae_ind, &re_max, &re_ind); xfprintf(fp, "KKT.DB: max.abs.err = %.2e on %s %d\n", ae_max, ae_ind <= P->m ? "row" : "column", ae_ind <= P->m ? ae_ind : ae_ind - P->m); xfprintf(fp, " max.rel.err = %.2e on %s %d\n", re_max, re_ind <= P->m ? "row" : "column", re_ind <= P->m ? re_ind : re_ind - P->m); xfprintf(fp, "%8s%s\n", "", re_max <= 1e-9 ? "High quality" : re_max <= 1e-6 ? "Medium quality" : re_max <= 1e-3 ? "Low quality" : "DUAL SOLUTION IS INFEASIBLE") ; xfprintf(fp, "\n"); xfprintf(fp, "End of output\n"); #if 0 /* FIXME */ xfflush(fp); #endif if (glp_ioerr(fp)) { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); ret = 1; goto done; } ret = 0; done: if (fp != NULL) glp_close(fp); return ret; }
static void maybe_check_results(const int ppl_status, const double ppl_optimum_value) { const char* ppl_status_string; const char* glpk_status_string; int glpk_status; int treat_as_lp = 0; glp_smcp glpk_smcp; if (!check_results) return; if (no_mip || glpk_lp_num_int == 0) treat_as_lp = 1; glp_set_obj_dir(glpk_lp, (maximize ? GLP_MAX : GLP_MIN)); glp_init_smcp(&glpk_smcp); /* Disable GLPK output. */ glpk_smcp.msg_lev = GLP_MSG_OFF; if (treat_as_lp) { /* Set the problem class to LP: MIP problems are thus treated as LP ones. */ glp_exact(glpk_lp, &glpk_smcp); glpk_status = glp_get_status(glpk_lp); } else { /* MIP case. */ glp_simplex(glpk_lp, &glpk_smcp); glpk_status = glp_get_status(glpk_lp); if (glpk_status != GLP_NOFEAS && glpk_status != GLP_UNBND) { glp_iocp glpk_iocp; glp_init_iocp(&glpk_iocp); /* Disable GLPK output. */ glpk_iocp.msg_lev = GLP_MSG_OFF; glp_intopt(glpk_lp, &glpk_iocp); glpk_status = glp_mip_status(glpk_lp); } } /* If no_optimization is enabled, the second case is not possibile. */ if (!((ppl_status == PPL_MIP_PROBLEM_STATUS_UNFEASIBLE && glpk_status == GLP_NOFEAS) || (ppl_status == PPL_MIP_PROBLEM_STATUS_UNBOUNDED && glpk_status == GLP_UNBND) || (ppl_status == PPL_MIP_PROBLEM_STATUS_OPTIMIZED && (glpk_status == GLP_OPT /* If no_optimization is enabled, check if the problem is unbounded for GLPK. */ || (no_optimization && (glpk_status == GLP_UNBND || glpk_status == GLP_UNDEF)))))) { if (ppl_status == PPL_MIP_PROBLEM_STATUS_UNFEASIBLE) ppl_status_string = "unfeasible"; else if (ppl_status == PPL_MIP_PROBLEM_STATUS_UNBOUNDED) ppl_status_string = "unbounded"; else if (ppl_status == PPL_MIP_PROBLEM_STATUS_OPTIMIZED) ppl_status_string = "optimizable"; else ppl_status_string = "<?>"; switch (glpk_status) { case GLP_NOFEAS: glpk_status_string = "unfeasible"; break; case GLP_UNBND: glpk_status_string = "unbounded"; break; case GLP_OPT: glpk_status_string = "optimizable"; break; case GLP_UNDEF: glpk_status_string = "undefined"; break; default: glpk_status_string = "<?>"; break; } error("check failed: for GLPK the problem is %s, not %s", glpk_status_string, ppl_status_string); check_results_failed = 1; } else if (!no_optimization && ppl_status == PPL_MIP_PROBLEM_STATUS_OPTIMIZED) { double glpk_optimum_value = (treat_as_lp ? glp_get_obj_val(glpk_lp) : glp_mip_obj_val(glpk_lp)); if (fabs(ppl_optimum_value - glpk_optimum_value) > check_threshold) { error("check failed: for GLPK the problem's optimum is %.20g," " not %.20g", glpk_optimum_value, ppl_optimum_value); check_results_failed = 1; } } return; }
int c_simplex_sparse(int m, int n, DMAT(c), DMAT(b), DVEC(s)) { glp_prob *lp; lp = glp_create_prob(); glp_set_obj_dir(lp, GLP_MAX); int i,j,k; int tot = cr - n; glp_add_rows(lp, m); glp_add_cols(lp, n); //printf("%d %d\n",m,n); // the first n values for (k=1;k<=n;k++) { glp_set_obj_coef(lp, k, AT(c, k-1, 2)); //printf("%d %f\n",k,AT(c, k-1, 2)); } int * ia = malloc((1+tot)*sizeof(int)); int * ja = malloc((1+tot)*sizeof(int)); double * ar = malloc((1+tot)*sizeof(double)); for (k=1; k<= tot; k++) { ia[k] = rint(AT(c,k-1+n,0)); ja[k] = rint(AT(c,k-1+n,1)); ar[k] = AT(c,k-1+n,2); //printf("%d %d %f\n",ia[k],ja[k],ar[k]); } glp_load_matrix(lp, tot, ia, ja, ar); int t; for (i=1;i<=m;i++) { switch((int)rint(AT(b,i-1,0))) { case 0: { t = GLP_FR; break; } case 1: { t = GLP_LO; break; } case 2: { t = GLP_UP; break; } case 3: { t = GLP_DB; break; } default: { t = GLP_FX; break; } } glp_set_row_bnds(lp, i, t , AT(b,i-1,1), AT(b,i-1,2)); } for (j=1;j<=n;j++) { switch((int)rint(AT(b,m+j-1,0))) { case 0: { t = GLP_FR; break; } case 1: { t = GLP_LO; break; } case 2: { t = GLP_UP; break; } case 3: { t = GLP_DB; break; } default: { t = GLP_FX; break; } } glp_set_col_bnds(lp, j, t , AT(b,m+j-1,1), AT(b,m+j-1,2)); } glp_term_out(0); glp_simplex(lp, NULL); sp[0] = glp_get_status(lp); sp[1] = glp_get_obj_val(lp); for (k=1; k<=n; k++) { sp[k+1] = glp_get_col_prim(lp, k); } glp_delete_prob(lp); free(ia); free(ja); free(ar); return 0; }
double solve_glp_grb(glp_prob *mip, wrapper_params *par){ GLPK_out = par->glp_out; GRB_out = par->grb_out; double obj_val; /** GLPK: Generate Variable indexing **/ glp_create_index(mip); /** GLPK: Generate LP **/ glp_write_mps(mip, GLP_MPS_FILE, NULL, "tmp.mps"); /************/ /** GUROBI **/ /************/ retGRB = GRBloadenv(&env, NULL); if (retGRB || env == NULL) { fprintf(stderr, "Error: could not create environment\n"); exit(1); } retGRB = GRBsetintparam(env, "OutputFlag", GRB_out?1:0); if (retGRB) freeMem(); //retGRB = GRBsetintparam(env, "Sensitivity", 1); //if (retGRB) freeMem(); /** GUROBI: Read model **/ retGRB = GRBreadmodel(env, "tmp.mps", &model); if (retGRB) freeMem(); /** Remove utility files from disk **/ //remove("tmp.mps"); /** GUROBI: Get environment **/ mipenv = GRBgetenv(model); if (!mipenv) freeMem(); /** GUROBI: Set parameters **/ /** GUROBI: Ask for more precision **/ retGRB = GRBsetdblparam(mipenv, "FeasibilityTol", 10E-6); if (retGRB) freeMem(); retGRB = GRBsetdblparam(mipenv, "IntFeasTol", 10E-5); if (retGRB) freeMem(); retGRB = GRBsetdblparam(mipenv, "MIPgap", 10E-6); if (retGRB) freeMem(); /* * Playing with gurobi parameters and attr*/ //gurobi_set_basis(); retGRB = GRBsetintparam(mipenv, "Cuts", 3); if (retGRB) freeMem(); retGRB = GRBsetintparam(mipenv, "RootMethod", 1); if (retGRB) freeMem(); retGRB = GRBsetintparam(mipenv, "Symmetry", -1); if (retGRB) freeMem(); /** GUROBI: get numvars and numrows **/ retGRB = GRBgetintattr(model, "NumVars", &numvars); if (retGRB) freeMem(); /** Test variable names */ for(int j=0;j<numvars;j++){ retGRB = GRBgetstrattrelement(model, "VarName", j, &nameGRB); printf("GRB Var %d Name %s\n",j,nameGRB); } /** GUROBI: get model type **/ retGRB = GRBgetintattr(model, "IsMIP", &GRB_IsMIP); if (retGRB) freeMem(); /** GUROBI: Optimize model **/ retGRB = GRBoptimize(model); if (retGRB) freeMem(); /** GUROBI: Retreive the optimization status **/ GRBgetintattr(model, "Status", &retGRB); switch(retGRB){ case GRB_OPTIMAL: break; case GRB_INFEASIBLE : fprintf(stderr, "Error GRB optimization failed with code GRB_INFEASIBLE\n"); case GRB_INF_OR_UNBD : fprintf(stderr, "Error GRB optimization failed with code GRB_INF_OR_UNBD \n"); case GRB_UNBOUNDED : fprintf(stderr, "Error GRB optimization failed with code GRB_UNBOUNDED \n"); case GRB_CUTOFF : fprintf(stderr, "Error GRB optimization failed with code GRB_CUTOFF \n"); case GRB_ITERATION_LIMIT : fprintf(stderr, "Error GRB optimization failed with code GRB_ITERATION_LIMIT \n"); case GRB_NODE_LIMIT : fprintf(stderr, "Error GRB optimization failed with code GRB_NODE_LIMIT \n"); case GRB_TIME_LIMIT : fprintf(stderr, "Error GRB optimization failed with code GRB_TIME_LIMIT \n"); case GRB_SOLUTION_LIMIT : fprintf(stderr, "Error GRB optimization failed with code GRB_SOLUTION_LIMIT \n"); case GRB_INTERRUPTED : fprintf(stderr, "Error GRB optimization failed with code GRB_INTERRUPTED \n"); case GRB_SUBOPTIMAL : fprintf(stderr, "Error GRB optimization failed with code GRB_SUBOPTIMAL \n"); case GRB_NUMERIC : fprintf(stderr, "Error GRB optimization failed with code GRB_NUMERIC \n"); /** GUROBI: Quit in any case non optimal **/ freeMem(); } /** GUROBI: Get obj function value **/ retGRB = GRBgetdblattr(model, "IntVio", &tmp); if (retGRB) freeMem(); retGRB = GRBgetdblattr(model, "ObjBound", &bound); if (retGRB) freeMem(); retGRB = GRBgetdblattr(model, "ObjVal", &tmp); if (retGRB) freeMem(); /* ********************** */ obj_val = tmp; /* ************ */ if (verbose) printf ("Objective %lf\n", tmp); if (verbose) printf ("Best bound %lf\n", bound); if (verbose) printf ("Absolute gap %lf\n", fabs(tmp - bound)); /** GUROBI: Get variable values **/ for (j = 0; j < numvars; ++j){ retGRB = GRBgetdblattrelement(model, "X", j, &tmp); if (retGRB) freeMem(); retGRB = GRBgetstrattrelement(model, "VarName", j, &nameGRB); printf("GRB Var %d Name %s\n",j,nameGRB); if (retGRB) freeMem(); retGRB = GRBgetcharattrelement(model, "VType", j, &type); if (retGRB) freeMem(); /** GLPK search variable index by name **/ col_index = glp_find_col(mip, nameGRB); if (col_index != 0){ /** GLPK set variable bounds **/ if ((type == 'B') || (type == 'I')){ if (verbose) printf ("Variable %s is of type %c value %lf fixed to %lf\n", nameGRB, type, tmp, round(tmp)); glp_set_col_bnds(mip, col_index, GLP_FX, round(tmp), round(tmp)); } else{ if (verbose) printf ("Variable %s is of type %c value %lf fixed to %lf\n", nameGRB, type, tmp, tmp); glp_set_col_bnds(mip, col_index, GLP_FX, tmp, tmp); } } } if (GRB_IsMIP){ /** GLPK initialize parameters **/ iparm = (glp_iocp*) malloc(sizeof(glp_iocp)); glp_init_iocp(iparm); iparm->presolve = GLP_ON; iparm->mip_gap = glpk_iparm_mip_gap; iparm->tol_int = glpk_iparm_tol_int; iparm->tol_obj = glpk_iparm_tol_obj; /** GLPK get the optimal integer solution **/ ret = glp_intopt(mip, iparm); if (ret){ fprintf(stderr, "glp_intopt, Error on optimizing the model : %d \n", ret); freeMem(); } ret = glp_mip_status(mip); switch (ret){ case GLP_OPT: break; case GLP_FEAS: fprintf(stderr, "Error GLPK simplex is not optimal, GLP_FEAS, code %d\n", ret); freeMem(); case GLP_NOFEAS: fprintf(stderr, "Error GLPK simplex is not optimal, GLP_NOFEAS, code %d\n", ret); freeMem(); case GLP_UNDEF: fprintf(stderr, "Error GLPK simplex is not optimal, GLP_UNDEF, code %d\n", ret); freeMem(); } } else{ /*GLPK initialize parameters */ parm = (glp_smcp*) malloc(sizeof(glp_smcp)); glp_init_smcp(parm); parm->meth = GLP_DUALP; parm->tol_bnd = 10E-4; parm->tol_dj = 10E-4; /* GLPK get the optimal basis */ //ret = glp_simplex(mip, parm); if (ret){ fprintf(stderr, "glp_simplex, Error on optimizing the model : %d \n", ret); freeMem(); } ret = glp_get_status(mip); switch (ret){ case GLP_OPT: break; case GLP_FEAS: fprintf(stderr, "Error GLPK simplex is not optimal, GLP_FEAS, code %d\n", ret); freeMem(); case GLP_INFEAS: fprintf(stderr, "Error GLPK simplex is not optimal, GLP_INFEAS, code %d\n", ret); freeMem(); case GLP_NOFEAS: fprintf(stderr, "Error GLPK simplex is not optimal, GLP_NOFEAS, code %d\n", ret); freeMem(); case GLP_UNBND: fprintf(stderr, "Error GLPK simplex is not optimal, GLP_UNBND, code %d\n", ret); freeMem(); case GLP_UNDEF: fprintf(stderr, "Error GLPK simplex is not optimal, GLP_UNDEF, code %d\n", ret); freeMem(); } } //GRBmodel *fmod = fixed_model(model); //gurobi_sens_output(fmod, "/tmp/sens.sol"); GRBwrite(model, "/tmp/model.sol"); /** GUROBI: free structures **/ if (model) GRBfreemodel(model); if (env) GRBfreeenv(env); return obj_val; }
OptSolutionData* GLPKRunSolver(int ProbType) { OptSolutionData* NewSolution = NULL; int NumVariables = glp_get_num_cols(GLPKModel); int Status = 0; if (ProbType == MILP) { Status = glp_simplex(GLPKModel, NULL); // Use default settings if (Status != 0) { FErrorFile() << "Failed to optimize problem." << endl; FlushErrorFile(); return NULL; } Status = glp_intopt(GLPKModel, NULL); // Use default settings if (Status != 0) { FErrorFile() << "Failed to optimize problem." << endl; FlushErrorFile(); return NULL; } NewSolution = new OptSolutionData; Status = glp_mip_status(GLPKModel); if (Status == GLP_UNDEF || Status == GLP_NOFEAS) { NewSolution->Status = INFEASIBLE; return NewSolution; } else if (Status == GLP_FEAS) { NewSolution->Status = UNBOUNDED; return NewSolution; } else if (Status == GLP_OPT) { NewSolution->Status = SUCCESS; } else { delete NewSolution; FErrorFile() << "Problem status unrecognized." << endl; FlushErrorFile(); return NULL; } NewSolution->Objective = glp_mip_obj_val(GLPKModel); NewSolution->SolutionData.resize(NumVariables); for (int i=0; i < NumVariables; i++) { NewSolution->SolutionData[i] = glp_mip_col_val(GLPKModel, i+1); } } else if (ProbType == LP) { //First we check the basis matrix to ensure it is not singular if (glp_warm_up(GLPKModel) != 0) { glp_adv_basis(GLPKModel, 0); } Status = glp_simplex(GLPKModel, NULL); // Use default settings if (Status == GLP_EBADB) { /* the basis is invalid; build some valid basis */ glp_adv_basis(GLPKModel, 0); Status = glp_simplex(GLPKModel, NULL); // Use default settings } if (Status != 0) { FErrorFile() << "Failed to optimize problem." << endl; FlushErrorFile(); return NULL; } NewSolution = new OptSolutionData; Status = glp_get_status(GLPKModel); if (Status == GLP_INFEAS || Status == GLP_NOFEAS || Status == GLP_UNDEF) { cout << "Model is infeasible" << endl; FErrorFile() << "Model is infeasible" << endl; FlushErrorFile(); NewSolution->Status = INFEASIBLE; return NewSolution; } else if (Status == GLP_FEAS || Status == GLP_UNBND) { cout << "Model is unbounded" << endl; FErrorFile() << "Model is unbounded" << endl; FlushErrorFile(); NewSolution->Status = UNBOUNDED; return NewSolution; } else if (Status == GLP_OPT) { NewSolution->Status = SUCCESS; } else { delete NewSolution; FErrorFile() << "Problem status unrecognized." << endl; FlushErrorFile(); return NULL; } NewSolution->Objective = glp_get_obj_val(GLPKModel); NewSolution->SolutionData.resize(NumVariables); for (int i=0; i < NumVariables; i++) { NewSolution->SolutionData[i] = glp_get_col_prim(GLPKModel, i+1); } } else { FErrorFile() << "Optimization problem type cannot be handled by GLPK solver." << endl; FlushErrorFile(); return NULL; } return NewSolution; }
static PyObject* LPX_write(LPXObject *self, PyObject *args, PyObject *keywds) { static char* kwlist[] = {"mps", "freemps", "prob", "sol", "sens_bnds", "ips", "mip", NULL}; char* fnames[] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL}; char* fname; const char* err_msg = "writer for '%s' failed to write to '%s'"; int rv; rv = PyArg_ParseTupleAndKeywords(args, keywds, "|sssssss", kwlist, fnames,fnames+1,fnames+2,fnames+3, fnames+4,fnames+5,fnames+6); if (!rv) return NULL; fname = fnames[0]; if (fname != NULL) { rv = glp_write_mps(LP, GLP_MPS_DECK, NULL, fname); if (rv != 0) { PyErr_Format(PyExc_RuntimeError, err_msg, kwlist[0], fname); return NULL; } } fname = fnames[1]; if (fname != NULL) { rv = glp_write_mps(LP, GLP_MPS_FILE, NULL, fname); if (rv != 0) { PyErr_Format(PyExc_RuntimeError, err_msg, kwlist[1], fname); return NULL; } } fname = fnames[2]; if (fname != NULL) { rv = glp_write_lp(LP, NULL, fname); if (rv != 0) { PyErr_Format(PyExc_RuntimeError, err_msg, kwlist[2], fname); return NULL; } } fname = fnames[3]; if (fname != NULL) { rv = glp_print_sol(LP, fname); if (rv != 0) { PyErr_Format(PyExc_RuntimeError, err_msg, kwlist[3], fname); return NULL; } } fname = fnames[4]; if (fname != NULL) { if (glp_get_status(LP) == GLP_OPT && !glp_bf_exists(LP)) glp_factorize(LP); rv = glp_print_ranges(LP, 0, NULL, 0, fname); if (rv != 0) { PyErr_Format(PyExc_RuntimeError, err_msg, kwlist[4], fname); return NULL; } } fname = fnames[5]; if (fname != NULL) { rv = glp_print_ipt(LP, fname); if (rv != 0) { PyErr_Format(PyExc_RuntimeError, err_msg, kwlist[5], fname); return NULL; } } fname = fnames[6]; if (fname != NULL) { glp_print_mip(LP, fname); if (rv != 0) { PyErr_Format(PyExc_RuntimeError, err_msg, kwlist[6], fname); return NULL; } } Py_RETURN_NONE; }
void ios_feas_pump(glp_tree *T) { glp_prob *P = T->mip; int n = P->n; glp_prob *lp = NULL; struct VAR *var = NULL; RNG *rand = NULL; GLPCOL *col; glp_smcp parm; int j, k, new_x, nfail, npass, nv, ret, stalling; double dist, tol; xassert(glp_get_status(P) == GLP_OPT); /* this heuristic is applied only once on the root level */ if (!(T->curr->level == 0 && T->curr->solved == 1)) goto done; /* determine number of binary variables */ nv = 0; for (j = 1; j <= n; j++) { col = P->col[j]; /* if x[j] is continuous, skip it */ if (col->kind == GLP_CV) continue; /* if x[j] is fixed, skip it */ if (col->type == GLP_FX) continue; /* x[j] is non-fixed integer */ xassert(col->kind == GLP_IV); if (col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0) { /* x[j] is binary */ nv++; } else { /* x[j] is general integer */ if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("FPUMP heuristic cannot be applied due to genera" "l integer variables\n"); goto done; } } /* there must be at least one binary variable */ if (nv == 0) goto done; if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("Applying FPUMP heuristic...\n"); /* build the list of binary variables */ var = xcalloc(1+nv, sizeof(struct VAR)); k = 0; for (j = 1; j <= n; j++) { col = P->col[j]; if (col->kind == GLP_IV && col->type == GLP_DB) var[++k].j = j; } xassert(k == nv); /* create working problem object */ lp = glp_create_prob(); more: /* copy the original problem object to keep it intact */ glp_copy_prob(lp, P, GLP_OFF); /* we are interested to find an integer feasible solution, which is better than the best known one */ if (P->mip_stat == GLP_FEAS) { int *ind; double *val, bnd; /* add a row and make it identical to the objective row */ glp_add_rows(lp, 1); ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); for (j = 1; j <= n; j++) { ind[j] = j; val[j] = P->col[j]->coef; } glp_set_mat_row(lp, lp->m, n, ind, val); xfree(ind); xfree(val); /* introduce upper (minimization) or lower (maximization) bound to the original objective function; note that this additional constraint is not violated at the optimal point to LP relaxation */ #if 0 /* modified by xypron <*****@*****.**> */ if (P->dir == GLP_MIN) { bnd = P->mip_obj - 0.10 * (1.0 + fabs(P->mip_obj)); if (bnd < P->obj_val) bnd = P->obj_val; glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0); } else if (P->dir == GLP_MAX) { bnd = P->mip_obj + 0.10 * (1.0 + fabs(P->mip_obj)); if (bnd > P->obj_val) bnd = P->obj_val; glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0); } else xassert(P != P); #else bnd = 0.1 * P->obj_val + 0.9 * P->mip_obj; /* xprintf("bnd = %f\n", bnd); */ if (P->dir == GLP_MIN) glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0); else if (P->dir == GLP_MAX) glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0); else xassert(P != P); #endif } /* reset pass count */ npass = 0; /* invalidate the rounded point */ for (k = 1; k <= nv; k++) var[k].x = -1; pass: /* next pass starts here */ npass++; if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("Pass %d\n", npass); /* initialize minimal distance between the basic point and the rounded one obtained during this pass */ dist = DBL_MAX; /* reset failure count (the number of succeeded iterations failed to improve the distance) */ nfail = 0; /* if it is not the first pass, perturb the last rounded point rather than construct it from the basic solution */ if (npass > 1) { double rho, temp; if (rand == NULL) rand = rng_create_rand(); for (k = 1; k <= nv; k++) { j = var[k].j; col = lp->col[j]; rho = rng_uniform(rand, -0.3, 0.7); if (rho < 0.0) rho = 0.0; temp = fabs((double)var[k].x - col->prim); if (temp + rho > 0.5) var[k].x = 1 - var[k].x; } goto skip; } loop: /* innermost loop begins here */ /* round basic solution (which is assumed primal feasible) */ stalling = 1; for (k = 1; k <= nv; k++) { col = lp->col[var[k].j]; if (col->prim < 0.5) { /* rounded value is 0 */ new_x = 0; } else { /* rounded value is 1 */ new_x = 1; } if (var[k].x != new_x) { stalling = 0; var[k].x = new_x; } } /* if the rounded point has not changed (stalling), choose and flip some its entries heuristically */ if (stalling) { /* compute d[j] = |x[j] - round(x[j])| */ for (k = 1; k <= nv; k++) { col = lp->col[var[k].j]; var[k].d = fabs(col->prim - (double)var[k].x); } /* sort the list of binary variables by descending d[j] */ qsort(&var[1], nv, sizeof(struct VAR), fcmp); /* choose and flip some rounded components */ for (k = 1; k <= nv; k++) { if (k >= 5 && var[k].d < 0.35 || k >= 10) break; var[k].x = 1 - var[k].x; } } skip: /* check if the time limit has been exhausted */ if (T->parm->tm_lim < INT_MAX && (double)(T->parm->tm_lim - 1) <= 1000.0 * xdifftime(xtime(), T->tm_beg)) goto done; /* build the objective, which is the distance between the current (basic) point and the rounded one */ lp->dir = GLP_MIN; lp->c0 = 0.0; for (j = 1; j <= n; j++) lp->col[j]->coef = 0.0; for (k = 1; k <= nv; k++) { j = var[k].j; if (var[k].x == 0) lp->col[j]->coef = +1.0; else { lp->col[j]->coef = -1.0; lp->c0 += 1.0; } } /* minimize the distance with the simplex method */ glp_init_smcp(&parm); if (T->parm->msg_lev <= GLP_MSG_ERR) parm.msg_lev = T->parm->msg_lev; else if (T->parm->msg_lev <= GLP_MSG_ALL) { parm.msg_lev = GLP_MSG_ON; parm.out_dly = 10000; } ret = glp_simplex(lp, &parm); if (ret != 0) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_simplex returned %d\n", ret); goto done; } ret = glp_get_status(lp); if (ret != GLP_OPT) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_get_status returned %d\n", ret); goto done; } if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("delta = %g\n", lp->obj_val); /* check if the basic solution is integer feasible; note that it may be so even if the minimial distance is positive */ tol = 0.3 * T->parm->tol_int; for (k = 1; k <= nv; k++) { col = lp->col[var[k].j]; if (tol < col->prim && col->prim < 1.0 - tol) break; } if (k > nv) { /* okay; the basic solution seems to be integer feasible */ double *x = xcalloc(1+n, sizeof(double)); for (j = 1; j <= n; j++) { x[j] = lp->col[j]->prim; if (P->col[j]->kind == GLP_IV) x[j] = floor(x[j] + 0.5); } #if 1 /* modified by xypron <*****@*****.**> */ /* reset direction and right-hand side of objective */ lp->c0 = P->c0; lp->dir = P->dir; /* fix integer variables */ for (k = 1; k <= nv; k++) #if 0 /* 18/VI-2013; fixed by mao * this bug causes numerical instability, because column statuses * are not changed appropriately */ { lp->col[var[k].j]->lb = x[var[k].j]; lp->col[var[k].j]->ub = x[var[k].j]; lp->col[var[k].j]->type = GLP_FX; } #else glp_set_col_bnds(lp, var[k].j, GLP_FX, x[var[k].j], 0.); #endif /* copy original objective function */ for (j = 1; j <= n; j++) lp->col[j]->coef = P->col[j]->coef; /* solve original LP and copy result */ ret = glp_simplex(lp, &parm); if (ret != 0) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_simplex returned %d\n", ret); goto done; } ret = glp_get_status(lp); if (ret != GLP_OPT) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_get_status returned %d\n", ret); goto done; } for (j = 1; j <= n; j++) if (P->col[j]->kind != GLP_IV) x[j] = lp->col[j]->prim; #endif ret = glp_ios_heur_sol(T, x); xfree(x); if (ret == 0) { /* the integer solution is accepted */ if (ios_is_hopeful(T, T->curr->bound)) { /* it is reasonable to apply the heuristic once again */ goto more; } else { /* the best known integer feasible solution just found is close to optimal solution to LP relaxation */ goto done; } } }
int DBWorker::_RememberRun(CMyProblem &P, int idobjectives, const char* modelfile, double time, bool mip, int idruns) { int idrun = -1; try { sql::PreparedStatement *PrepStmt; sql::ResultSet *res; PrepStmt = con->prepareStatement( "INSERT INTO runs(idobjectives,modelfile,runtype,res_status,res_value,time_in_seconds,idruns) VALUES(?,?,?,?,?,?,?)" ); PrepStmt->setInt(1, idobjectives); PrepStmt->setString(2, modelfile); PrepStmt->setString(3, mip ? "mip" : "lp"); if(!mip) { PrepStmt->setInt(4, glp_get_status(P.GetProblem())); PrepStmt->setDouble(5, glp_get_obj_val(P.GetProblem())); PrepStmt->setNull(7,0); } else { PrepStmt->setInt(4, glp_mip_status(P.GetProblem())); PrepStmt->setDouble(5, glp_mip_obj_val(P.GetProblem())); PrepStmt->setInt(7,idruns); } PrepStmt->setDouble(6, time); PrepStmt->execute(); delete PrepStmt; if(!mip) { PrepStmt = con->prepareStatement( "SELECT LAST_INSERT_ID()" ); res = PrepStmt->executeQuery(); delete PrepStmt; res->next(); idrun = res->getInt(1); delete res; } else { idrun = idruns; } cout << "Run ID " << idrun << endl; PrepStmt = con->prepareStatement( "INSERT INTO results(idrun,var_name,i,j,value,runtype) VALUES(?,?,?,?,?,?)" ); PrepStmt->setInt(1, idrun); PrepStmt->setString(6, mip ? "mip" : "lp"); vector<vector<double>> arr; for (int vvv=1; vvv>=0; vvv--) { char* var_name = (vvv ? "x" : "y"); GetSolArray(P.GetProblem(),var_name,arr,mip); PrepStmt->setString(2, var_name); int i=1; for (std::vector<vector<double>>::iterator it = arr.begin() ; it != arr.end(); ++it) { int j=1; for (std::vector<double>::iterator it2 = (*it).begin() ; it2 != (*it).end(); ++it2) { PrepStmt->setInt(3, i); PrepStmt->setInt(4, j); PrepStmt->setDouble(5, *it2); PrepStmt->execute(); j++; } i++; } } delete PrepStmt; } catch (sql::SQLException &e) { SQLError(e); } return idrun; }
int glp_main(int argc, const char *argv[]) { /* stand-alone LP/MIP solver */ struct csa _csa, *csa = &_csa; int ret; xlong_t start; /* perform initialization */ csa->prob = glp_create_prob(); glp_get_bfcp(csa->prob, &csa->bfcp); glp_init_smcp(&csa->smcp); csa->smcp.presolve = GLP_ON; glp_init_iocp(&csa->iocp); csa->iocp.presolve = GLP_ON; csa->tran = NULL; csa->graph = NULL; csa->format = FMT_MPS_FILE; csa->in_file = NULL; csa->ndf = 0; csa->out_dpy = NULL; csa->solution = SOL_BASIC; csa->in_res = NULL; csa->dir = 0; csa->scale = 1; csa->out_sol = NULL; csa->out_res = NULL; csa->out_bnds = NULL; csa->check = 0; csa->new_name = NULL; csa->out_mps = NULL; csa->out_freemps = NULL; csa->out_cpxlp = NULL; csa->out_pb = NULL; csa->out_npb = NULL; csa->log_file = NULL; csa->crash = USE_ADV_BASIS; csa->exact = 0; csa->xcheck = 0; csa->nomip = 0; /* parse command-line parameters */ ret = parse_cmdline(csa, argc, argv); if (ret < 0) { ret = EXIT_SUCCESS; goto done; } if (ret > 0) { ret = EXIT_FAILURE; goto done; } /*--------------------------------------------------------------*/ /* remove all output files specified in the command line */ if (csa->out_dpy != NULL) remove(csa->out_dpy); if (csa->out_sol != NULL) remove(csa->out_sol); if (csa->out_res != NULL) remove(csa->out_res); if (csa->out_bnds != NULL) remove(csa->out_bnds); if (csa->out_mps != NULL) remove(csa->out_mps); if (csa->out_freemps != NULL) remove(csa->out_freemps); if (csa->out_cpxlp != NULL) remove(csa->out_cpxlp); if (csa->out_pb != NULL) remove(csa->out_pb); if (csa->out_npb != NULL) remove(csa->out_npb); if (csa->log_file != NULL) remove(csa->log_file); /*--------------------------------------------------------------*/ /* open log file, if required */ if (csa->log_file != NULL) { if (lib_open_log(csa->log_file)) { xprintf("Unable to create log file\n"); ret = EXIT_FAILURE; goto done; } } /*--------------------------------------------------------------*/ /* read problem data from the input file */ if (csa->in_file == NULL) { xprintf("No input problem file specified; try %s --help\n", argv[0]); ret = EXIT_FAILURE; goto done; } if (csa->format == FMT_MPS_DECK) { ret = glp_read_mps(csa->prob, GLP_MPS_DECK, NULL, csa->in_file); if (ret != 0) err1: { xprintf("MPS file processing error\n"); ret = EXIT_FAILURE; goto done; } } else if (csa->format == FMT_MPS_FILE) { ret = glp_read_mps(csa->prob, GLP_MPS_FILE, NULL, csa->in_file); if (ret != 0) goto err1; } else if (csa->format == FMT_CPLEX_LP) { ret = glp_read_lp(csa->prob, NULL, csa->in_file); if (ret != 0) { xprintf("CPLEX LP file processing error\n"); ret = EXIT_FAILURE; goto done; } } else if (csa->format == FMT_MATHPROG) { int k; /* allocate the translator workspace */ csa->tran = glp_mpl_alloc_wksp(); /* read model section and optional data section */ if (glp_mpl_read_model(csa->tran, csa->in_file, csa->ndf > 0)) err2: { xprintf("MathProg model processing error\n"); ret = EXIT_FAILURE; goto done; } /* read optional data section(s), if necessary */ for (k = 1; k <= csa->ndf; k++) { if (glp_mpl_read_data(csa->tran, csa->in_data[k])) goto err2; } /* generate the model */ if (glp_mpl_generate(csa->tran, csa->out_dpy)) goto err2; /* build the problem instance from the model */ glp_mpl_build_prob(csa->tran, csa->prob); } else if (csa->format == FMT_MIN_COST) { csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data)); ret = glp_read_mincost(csa->graph, offsetof(v_data, rhs), offsetof(a_data, low), offsetof(a_data, cap), offsetof(a_data, cost), csa->in_file); if (ret != 0) { xprintf("DIMACS file processing error\n"); ret = EXIT_FAILURE; goto done; } glp_mincost_lp(csa->prob, csa->graph, GLP_ON, offsetof(v_data, rhs), offsetof(a_data, low), offsetof(a_data, cap), offsetof(a_data, cost)); glp_set_prob_name(csa->prob, csa->in_file); } else if (csa->format == FMT_MAX_FLOW) { int s, t; csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data)); ret = glp_read_maxflow(csa->graph, &s, &t, offsetof(a_data, cap), csa->in_file); if (ret != 0) { xprintf("DIMACS file processing error\n"); ret = EXIT_FAILURE; goto done; } glp_maxflow_lp(csa->prob, csa->graph, GLP_ON, s, t, offsetof(a_data, cap)); glp_set_prob_name(csa->prob, csa->in_file); } else xassert(csa != csa); /*--------------------------------------------------------------*/ /* change problem name, if required */ if (csa->new_name != NULL) glp_set_prob_name(csa->prob, csa->new_name); /* change optimization direction, if required */ if (csa->dir != 0) glp_set_obj_dir(csa->prob, csa->dir); /* order rows and columns of the constraint matrix */ lpx_order_matrix(csa->prob); /*--------------------------------------------------------------*/ /* write problem data in fixed MPS format, if required */ if (csa->out_mps != NULL) { ret = glp_write_mps(csa->prob, GLP_MPS_DECK, NULL, csa->out_mps); if (ret != 0) { xprintf("Unable to write problem in fixed MPS format\n"); ret = EXIT_FAILURE; goto done; } } /* write problem data in free MPS format, if required */ if (csa->out_freemps != NULL) { ret = glp_write_mps(csa->prob, GLP_MPS_FILE, NULL, csa->out_freemps); if (ret != 0) { xprintf("Unable to write problem in free MPS format\n"); ret = EXIT_FAILURE; goto done; } } /* write problem data in CPLEX LP format, if required */ if (csa->out_cpxlp != NULL) { ret = glp_write_lp(csa->prob, NULL, csa->out_cpxlp); if (ret != 0) { xprintf("Unable to write problem in CPLEX LP format\n"); ret = EXIT_FAILURE; goto done; } } /* write problem data in OPB format, if required */ if (csa->out_pb != NULL) { ret = lpx_write_pb(csa->prob, csa->out_pb, 0, 0); if (ret != 0) { xprintf("Unable to write problem in OPB format\n"); ret = EXIT_FAILURE; goto done; } } /* write problem data in normalized OPB format, if required */ if (csa->out_npb != NULL) { ret = lpx_write_pb(csa->prob, csa->out_npb, 1, 1); if (ret != 0) { xprintf( "Unable to write problem in normalized OPB format\n"); ret = EXIT_FAILURE; goto done; } } /*--------------------------------------------------------------*/ /* if only problem data check is required, skip computations */ if (csa->check) { ret = EXIT_SUCCESS; goto done; } /*--------------------------------------------------------------*/ /* determine the solution type */ if (!csa->nomip && glp_get_num_int(csa->prob) + glp_get_num_bin(csa->prob) > 0) { if (csa->solution == SOL_INTERIOR) { xprintf("Interior-point method is not able to solve MIP pro" "blem; use --simplex\n"); ret = EXIT_FAILURE; goto done; } csa->solution = SOL_INTEGER; } /*--------------------------------------------------------------*/ /* if solution is provided, read it and skip computations */ if (csa->in_res != NULL) { if (csa->solution == SOL_BASIC) ret = glp_read_sol(csa->prob, csa->in_res); else if (csa->solution == SOL_INTERIOR) ret = glp_read_ipt(csa->prob, csa->in_res); else if (csa->solution == SOL_INTEGER) ret = glp_read_mip(csa->prob, csa->in_res); else xassert(csa != csa); if (ret != 0) { xprintf("Unable to read problem solution\n"); ret = EXIT_FAILURE; goto done; } goto skip; } /*--------------------------------------------------------------*/ /* scale the problem data, if required */ if (csa->scale) { if (csa->solution == SOL_BASIC && !csa->smcp.presolve || csa->solution == SOL_INTERIOR || csa->solution == SOL_INTEGER && !csa->iocp.presolve) glp_scale_prob(csa->prob, GLP_SF_AUTO); } /* construct starting LP basis */ if (csa->solution == SOL_BASIC && !csa->smcp.presolve || csa->solution == SOL_INTEGER && !csa->iocp.presolve) { if (csa->crash == USE_STD_BASIS) glp_std_basis(csa->prob); else if (csa->crash == USE_ADV_BASIS) glp_adv_basis(csa->prob, 0); else if (csa->crash == USE_CPX_BASIS) glp_cpx_basis(csa->prob); else xassert(csa != csa); } /*--------------------------------------------------------------*/ /* solve the problem */ start = xtime(); if (csa->solution == SOL_BASIC) { if (!csa->exact) { glp_set_bfcp(csa->prob, &csa->bfcp); glp_simplex(csa->prob, &csa->smcp); if (csa->xcheck) { if (csa->smcp.presolve && glp_get_status(csa->prob) != GLP_OPT) xprintf("If you need to check final basis for non-opt" "imal solution, use --nopresol\n"); else glp_exact(csa->prob, &csa->smcp); } if (csa->out_sol != NULL || csa->out_res != NULL) { if (csa->smcp.presolve && glp_get_status(csa->prob) != GLP_OPT) xprintf("If you need actual output for non-optimal solut" "ion, use --nopresol\n"); } } else glp_exact(csa->prob, &csa->smcp); } else if (csa->solution == SOL_INTERIOR) glp_interior(csa->prob, NULL); else if (csa->solution == SOL_INTEGER) { if (!csa->iocp.presolve) { glp_set_bfcp(csa->prob, &csa->bfcp); glp_simplex(csa->prob, &csa->smcp); } glp_intopt(csa->prob, &csa->iocp); } else xassert(csa != csa); /*--------------------------------------------------------------*/ /* display statistics */ xprintf("Time used: %.1f secs\n", xdifftime(xtime(), start)); { xlong_t tpeak; char buf[50]; lib_mem_usage(NULL, NULL, NULL, &tpeak); xprintf("Memory used: %.1f Mb (%s bytes)\n", xltod(tpeak) / 1048576.0, xltoa(tpeak, buf)); } /*--------------------------------------------------------------*/ skip: /* postsolve the model, if necessary */ if (csa->tran != NULL) { if (csa->solution == SOL_BASIC) ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_SOL); else if (csa->solution == SOL_INTERIOR) ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_IPT); else if (csa->solution == SOL_INTEGER) ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_MIP); else xassert(csa != csa); if (ret != 0) { xprintf("Model postsolving error\n"); ret = EXIT_FAILURE; goto done; } } /*--------------------------------------------------------------*/ /* write problem solution in printable format, if required */ if (csa->out_sol != NULL) { if (csa->solution == SOL_BASIC) ret = lpx_print_sol(csa->prob, csa->out_sol); else if (csa->solution == SOL_INTERIOR) ret = lpx_print_ips(csa->prob, csa->out_sol); else if (csa->solution == SOL_INTEGER) ret = lpx_print_mip(csa->prob, csa->out_sol); else xassert(csa != csa); if (ret != 0) { xprintf("Unable to write problem solution\n"); ret = EXIT_FAILURE; goto done; } } /* write problem solution in printable format, if required */ if (csa->out_res != NULL) { if (csa->solution == SOL_BASIC) ret = glp_write_sol(csa->prob, csa->out_res); else if (csa->solution == SOL_INTERIOR) ret = glp_write_ipt(csa->prob, csa->out_res); else if (csa->solution == SOL_INTEGER) ret = glp_write_mip(csa->prob, csa->out_res); else xassert(csa != csa); if (ret != 0) { xprintf("Unable to write problem solution\n"); ret = EXIT_FAILURE; goto done; } } /* write sensitivity bounds information, if required */ if (csa->out_bnds != NULL) { if (csa->solution == SOL_BASIC) { ret = lpx_print_sens_bnds(csa->prob, csa->out_bnds); if (ret != 0) { xprintf("Unable to write sensitivity bounds information " "\n"); ret = EXIT_FAILURE; goto done; } } else xprintf("Cannot write sensitivity bounds information for in" "terior-point or MIP solution\n"); } /*--------------------------------------------------------------*/ /* all seems to be ok */ ret = EXIT_SUCCESS; /*--------------------------------------------------------------*/ done: /* delete the LP/MIP problem object */ if (csa->prob != NULL) glp_delete_prob(csa->prob); /* free the translator workspace, if necessary */ if (csa->tran != NULL) glp_mpl_free_wksp(csa->tran); /* delete the network problem object, if necessary */ if (csa->graph != NULL) glp_delete_graph(csa->graph); xassert(gmp_pool_count() == 0); gmp_free_mem(); /* close log file, if necessary */ if (csa->log_file != NULL) lib_close_log(); /* check that no memory blocks are still allocated */ { int count; xlong_t total; lib_mem_usage(&count, NULL, &total, NULL); if (count != 0) xerror("Error: %d memory block(s) were lost\n", count); xassert(count == 0); xassert(total.lo == 0 && total.hi == 0); } /* free the library environment */ lib_free_env(); /* return to the control program */ return ret; }
int lpx_print_sens_bnds(LPX *lp, const char *fname) { /* write bounds sensitivity information */ if (glp_get_status(lp) == GLP_OPT && !glp_bf_exists(lp)) glp_factorize(lp); return glp_print_ranges(lp, 0, NULL, 0, fname); }
static double eval_degrad(glp_prob *P, int j, double bnd) { /* compute degradation of the objective on fixing x[j] at given value with a limited number of dual simplex iterations */ /* this routine fixes column x[j] at specified value bnd, solves resulting LP, and returns a lower bound to degradation of the objective, degrad >= 0 */ glp_prob *lp; glp_smcp parm; int ret; double degrad; /* the current basis must be optimal */ xassert(glp_get_status(P) == GLP_OPT); /* create a copy of P */ lp = glp_create_prob(); glp_copy_prob(lp, P, 0); /* fix column x[j] at specified value */ glp_set_col_bnds(lp, j, GLP_FX, bnd, bnd); /* try to solve resulting LP */ glp_init_smcp(&parm); parm.msg_lev = GLP_MSG_OFF; parm.meth = GLP_DUAL; parm.it_lim = 30; parm.out_dly = 1000; parm.meth = GLP_DUAL; ret = glp_simplex(lp, &parm); if (ret == 0 || ret == GLP_EITLIM) { if (glp_get_prim_stat(lp) == GLP_NOFEAS) { /* resulting LP has no primal feasible solution */ degrad = DBL_MAX; } else if (glp_get_dual_stat(lp) == GLP_FEAS) { /* resulting basis is optimal or at least dual feasible, so we have the correct lower bound to degradation */ if (P->dir == GLP_MIN) degrad = lp->obj_val - P->obj_val; else if (P->dir == GLP_MAX) degrad = P->obj_val - lp->obj_val; else xassert(P != P); /* degradation cannot be negative by definition */ /* note that the lower bound to degradation may be close to zero even if its exact value is zero due to round-off errors on computing the objective value */ if (degrad < 1e-6 * (1.0 + 0.001 * fabs(P->obj_val))) degrad = 0.0; } else { /* the final basis reported by the simplex solver is dual infeasible, so we cannot determine a non-trivial lower bound to degradation */ degrad = 0.0; } } else { /* the simplex solver failed */ degrad = 0.0; } /* delete the copy of P */ glp_delete_prob(lp); return degrad; }
static int branch_drtom(glp_tree *T, int *_next) { glp_prob *mip = T->mip; int m = mip->m; int n = mip->n; char *non_int = T->non_int; int j, jj, k, t, next, kase, len, stat, *ind; double x, dk, alfa, delta_j, delta_k, delta_z, dz_dn, dz_up, dd_dn, dd_up, degrad, *val; /* basic solution of LP relaxation must be optimal */ xassert(glp_get_status(mip) == GLP_OPT); /* allocate working arrays */ ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); /* nothing has been chosen so far */ jj = 0, degrad = -1.0; /* walk through the list of columns (structural variables) */ for (j = 1; j <= n; j++) { /* if j-th column is not marked as fractional, skip it */ if (!non_int[j]) continue; /* obtain (fractional) value of j-th column in basic solution of LP relaxation */ x = glp_get_col_prim(mip, j); /* since the value of j-th column is fractional, the column is basic; compute corresponding row of the simplex table */ len = glp_eval_tab_row(mip, m+j, ind, val); /* the following fragment computes a change in the objective function: delta Z = new Z - old Z, where old Z is the objective value in the current optimal basis, and new Z is the objective value in the adjacent basis, for two cases: 1) if new upper bound ub' = floor(x[j]) is introduced for j-th column (down branch); 2) if new lower bound lb' = ceil(x[j]) is introduced for j-th column (up branch); since in both cases the solution remaining dual feasible becomes primal infeasible, one implicit simplex iteration is performed to determine the change delta Z; it is obvious that new Z, which is never better than old Z, is a lower (minimization) or upper (maximization) bound of the objective function for down- and up-branches. */ for (kase = -1; kase <= +1; kase += 2) { /* if kase < 0, the new upper bound of x[j] is introduced; in this case x[j] should decrease in order to leave the basis and go to its new upper bound */ /* if kase > 0, the new lower bound of x[j] is introduced; in this case x[j] should increase in order to leave the basis and go to its new lower bound */ /* apply the dual ratio test in order to determine which auxiliary or structural variable should enter the basis to keep dual feasibility */ k = glp_dual_rtest(mip, len, ind, val, kase, 1e-9); if (k != 0) k = ind[k]; /* if no non-basic variable has been chosen, LP relaxation of corresponding branch being primal infeasible and dual unbounded has no primal feasible solution; in this case the change delta Z is formally set to infinity */ if (k == 0) { delta_z = (T->mip->dir == GLP_MIN ? +DBL_MAX : -DBL_MAX); goto skip; } /* row of the simplex table that corresponds to non-basic variable x[k] choosen by the dual ratio test is: x[j] = ... + alfa * x[k] + ... where alfa is the influence coefficient (an element of the simplex table row) */ /* determine the coefficient alfa */ for (t = 1; t <= len; t++) if (ind[t] == k) break; xassert(1 <= t && t <= len); alfa = val[t]; /* since in the adjacent basis the variable x[j] becomes non-basic, knowing its value in the current basis we can determine its change delta x[j] = new x[j] - old x[j] */ delta_j = (kase < 0 ? floor(x) : ceil(x)) - x; /* and knowing the coefficient alfa we can determine the corresponding change delta x[k] = new x[k] - old x[k], where old x[k] is a value of x[k] in the current basis, and new x[k] is a value of x[k] in the adjacent basis */ delta_k = delta_j / alfa; /* Tomlin noticed that if the variable x[k] is of integer kind, its change cannot be less (eventually) than one in the magnitude */ if (k > m && glp_get_col_kind(mip, k-m) != GLP_CV) { /* x[k] is structural integer variable */ if (fabs(delta_k - floor(delta_k + 0.5)) > 1e-3) { if (delta_k > 0.0) delta_k = ceil(delta_k); /* +3.14 -> +4 */ else delta_k = floor(delta_k); /* -3.14 -> -4 */ } } /* now determine the status and reduced cost of x[k] in the current basis */ if (k <= m) { stat = glp_get_row_stat(mip, k); dk = glp_get_row_dual(mip, k); } else { stat = glp_get_col_stat(mip, k-m); dk = glp_get_col_dual(mip, k-m); } /* if the current basis is dual degenerate, some reduced costs which are close to zero may have wrong sign due to round-off errors, so correct the sign of d[k] */ switch (T->mip->dir) { case GLP_MIN: if (stat == GLP_NL && dk < 0.0 || stat == GLP_NU && dk > 0.0 || stat == GLP_NF) dk = 0.0; break; case GLP_MAX: if (stat == GLP_NL && dk > 0.0 || stat == GLP_NU && dk < 0.0 || stat == GLP_NF) dk = 0.0; break; default: xassert(T != T); } /* now knowing the change of x[k] and its reduced cost d[k] we can compute the corresponding change in the objective function delta Z = new Z - old Z = d[k] * delta x[k]; note that due to Tomlin's modification new Z can be even worse than in the adjacent basis */ delta_z = dk * delta_k; skip: /* new Z is never better than old Z, therefore the change delta Z is always non-negative (in case of minimization) or non-positive (in case of maximization) */ switch (T->mip->dir) { case GLP_MIN: xassert(delta_z >= 0.0); break; case GLP_MAX: xassert(delta_z <= 0.0); break; default: xassert(T != T); } /* save the change in the objective fnction for down- and up-branches, respectively */ if (kase < 0) dz_dn = delta_z; else dz_up = delta_z; } /* thus, in down-branch no integer feasible solution can be better than Z + dz_dn, and in up-branch no integer feasible solution can be better than Z + dz_up, where Z is value of the objective function in the current basis */ /* following the heuristic by Driebeck and Tomlin we choose a column (i.e. structural variable) which provides largest degradation of the objective function in some of branches; besides, we select the branch with smaller degradation to be solved next and keep other branch with larger degradation in the active list hoping to minimize the number of further backtrackings */ if (degrad < fabs(dz_dn) || degrad < fabs(dz_up)) { jj = j; if (fabs(dz_dn) < fabs(dz_up)) { /* select down branch to be solved next */ next = GLP_DN_BRNCH; degrad = fabs(dz_up); } else { /* select up branch to be solved next */ next = GLP_UP_BRNCH; degrad = fabs(dz_dn); } /* save the objective changes for printing */ dd_dn = dz_dn, dd_up = dz_up; /* if down- or up-branch has no feasible solution, we does not need to consider other candidates (in principle, the corresponding branch could be pruned right now) */ if (degrad == DBL_MAX) break; } } /* free working arrays */ xfree(ind); xfree(val); /* something must be chosen */ xassert(1 <= jj && jj <= n); #if 1 /* 02/XI-2009 */ if (degrad < 1e-6 * (1.0 + 0.001 * fabs(mip->obj_val))) { jj = branch_mostf(T, &next); goto done; } #endif if (T->parm->msg_lev >= GLP_MSG_DBG) { xprintf("branch_drtom: column %d chosen to branch on\n", jj); if (fabs(dd_dn) == DBL_MAX) xprintf("branch_drtom: down-branch is infeasible\n"); else xprintf("branch_drtom: down-branch bound is %.9e\n", lpx_get_obj_val(mip) + dd_dn); if (fabs(dd_up) == DBL_MAX) xprintf("branch_drtom: up-branch is infeasible\n"); else xprintf("branch_drtom: up-branch bound is %.9e\n", lpx_get_obj_val(mip) + dd_up); } done: *_next = next; return jj; }
int main(int argc, char * argv[]) { int i,j; time(&initial); srand(SEED); /* Default values */ outFile = stdout; maxAlpha = 2; maxIter = 100; maxTime = 30; randomSeed = SEED; simpleOutput = 0; /* Read arguments */ if( argc > 7 ) argc = 7; switch(argc) { case 7: simpleOutput = atoi(argv[6]); case 6: if( !(randomSeed = atoi(argv[5])) ) leave(argv[0]); case 5: if( !(maxTime = atoi(argv[4])) ) leave(argv[0]); case 4: if( !(maxIter = atoi(argv[3])) ) leave(argv[0]); case 3: if( !(maxAlpha = atoi(argv[2])) ) leave(argv[0]); case 2: if( simpleOutput ) { if( !(outFile = fopen(argv[1],"a")) ) leave(argv[0]); break; } if( !(outFile = fopen(argv[1],"w")) ) leave(argv[0]); } readInput(stdin); /* Initiate positions */ for( i = 0 ; i < n ; ++i ) { pOrd[i].ideal = planes[i].ideal; pOrd[i].pos = i; } qsort (pOrd, n, sizeof(struct planeOrder), compIdealT); for( i = 0 ; i < n ; ++i ) { planes[pOrd[i].pos].pos = i; } /* Create lp instance */ glp_prob * Prob; Prob = glp_create_prob(); glp_set_prob_name(Prob, "Airplane Landing Problem"); glp_set_obj_name(Prob, "Cost"); /* Create basic constraints */ for( i = 0 ; i < n ; ++i ) { addBasicRestriction(Prob,i); } glp_create_index(Prob); /* Create separation constraints and order variables (&ij) if necessary */ for( i = 0 ; i < n ; ++i ) { for( j = i+1 ; j < n ; ++j ) { if( planes[i].latest >= planes[j].earliest && planes[j].latest >= planes[i].earliest ) { addOrderConstraint(Prob,i,j); } else if ( planes[i].latest < planes[j].earliest && planes[i].latest + planes[i].sep[j] >= planes[j].earliest ) { addSeparationConstraint(Prob, i, j); } else if ( planes[j].latest < planes[i].earliest && planes[j].latest + planes[j].sep[i] >= planes[i].earliest ) { addSeparationConstraint(Prob, j, i); } } } /* Write problem in MPS format so glpsol can (try to) solve it */ glp_write_mps(Prob, GLP_MPS_FILE, NULL,"mpsProblem.txt"); glp_delete_index(Prob); glp_create_index(Prob); /* GRASP */ /* Data to handle glp solving, time checking and solution generating */ glp_smcp * param = malloc(sizeof(glp_smcp)); glp_init_smcp(param); param->msg_lev = GLP_MSG_ERR; int solution[MAXSIZE], timeAux[MAXSIZE], t; double currResult = DBL_MAX, bestResult = DBL_MAX; alpha = 0; time_t start, curr; time(&start); for( t = 0 ; t < maxIter ; ++t ) { /* Greedy solution generation */ while(createSolution(solution,timeAux,0)) alpha = n; /* Building the right constraints */ mapSolution(Prob,solution); /* Solving with glpsol */ param->presolve = GLP_ON; glp_simplex(Prob,param); param->presolve = GLP_OFF; currResult = glp_get_obj_val(Prob); /* Local search using the first increase */ for( i = 0 ; i < n-1 ; ++i ) { /* Swap two adjacent planes */ swapConstraint(Prob,i,solution,0); glp_simplex(Prob,param); /* Check for improvements */ if( GLP_OPT == glp_get_status(Prob) && glp_get_obj_val(Prob) < currResult ) { currResult = glp_get_obj_val(Prob); /* Changing the solution */ int swp; swp = solution[i]; solution[i] = solution[i+1]; solution[i+1] = swp; /* Restarting */ i = -1; } else swapConstraint(Prob,i,solution,1); } /* Checking improvements */ if( bestResult > currResult ) { bestResult = currResult; for( i = 0 ; i < n ; ++i ) planes[solution[i]].pos = i; } /* Choosing alpha */ alpha = rand()%(maxAlpha+1); /* Is our time up? */ time(&curr); if( difftime(curr,start) > maxTime ) break; } /* Print Answer */ printResult(Prob, stdout); if( outFile ) { printResult(Prob, outFile); fclose(outFile); } return 0; }
int glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn, double *a, double *b, char *ctype, int *freeLB, double *lb, int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, int save_pb, char *save_filename, char *filetype, double *xmin, double *fmin, double *status, double *lambda, double *redcosts, double *time, double *mem) { int typx = 0; int method; clock_t t_start = clock(); // Obsolete //lib_set_fault_hook (NULL, glpk_fault_hook); //Redirect standard output if (glpIntParam[0] > 1) glp_term_hook (glpk_print_hook, NULL); else glp_term_hook (NULL, NULL); //-- Create an empty LP/MILP object glp_prob *lp = glp_create_prob (); //-- Set the sense of optimization if (sense == 1) glp_set_obj_dir (lp, GLP_MIN); else glp_set_obj_dir (lp, GLP_MAX); //-- Define the number of unknowns and their domains. glp_add_cols (lp, n); for (int i = 0; i < n; i++) { //-- Define type of the structural variables if (! freeLB[i] && ! freeUB[i]) glp_set_col_bnds (lp, i+1, GLP_DB, lb[i], ub[i]); else { if (! freeLB[i] && freeUB[i]) glp_set_col_bnds (lp, i+1, GLP_LO, lb[i], ub[i]); else { if (freeLB[i] && ! freeUB[i]) glp_set_col_bnds (lp, i+1, GLP_UP, lb[i], ub[i]); else glp_set_col_bnds (lp, i+1, GLP_FR, lb[i], ub[i]); } } // -- Set the objective coefficient of the corresponding // -- structural variable. No constant term is assumed. glp_set_obj_coef(lp,i+1,c[i]); if (isMIP) glp_set_col_kind (lp, i+1, vartype[i]); } glp_add_rows (lp, m); for (int i = 0; i < m; i++) { /* If the i-th row has no lower bound (types F,U), the corrispondent parameter will be ignored. If the i-th row has no upper bound (types F,L), the corrispondent parameter will be ignored. If the i-th row is of S type, the i-th LB is used, but the i-th UB is ignored. */ switch (ctype[i]) { case 'F': typx = GLP_FR; break; // upper bound case 'U': typx = GLP_UP; break; // lower bound case 'L': typx = GLP_LO; break; // fixed constraint case 'S': typx = GLP_FX; break; // double-bounded variable case 'D': typx = GLP_DB; break; } glp_set_row_bnds (lp, i+1, typx, b[i], b[i]); } // Load constraint matrix A glp_load_matrix (lp, nz, rn, cn, a); // Save problem if (save_pb) { if (!strcmp(filetype,"cplex")){ if (lpx_write_cpxlp (lp, save_filename) != 0) { mexErrMsgTxt("glpkcc: unable to write the problem"); longjmp (mark, -1); } }else{ if (!strcmp(filetype,"fixedmps")){ if (lpx_write_mps (lp, save_filename) != 0) { mexErrMsgTxt("glpkcc: unable to write the problem"); longjmp (mark, -1); } }else{ if (!strcmp(filetype,"freemps")){ if (lpx_write_freemps (lp, save_filename) != 0) { mexErrMsgTxt("glpkcc: unable to write the problem"); longjmp (mark, -1); } }else{// plain text if (lpx_print_prob (lp, save_filename) != 0) { mexErrMsgTxt("glpkcc: unable to write the problem"); longjmp (mark, -1); } } } } } //-- scale the problem data (if required) if (glpIntParam[1] && (! glpIntParam[16] || lpsolver != 1)) lpx_scale_prob (lp); //-- build advanced initial basis (if required) if (lpsolver == 1 && ! glpIntParam[16]) lpx_adv_basis (lp); glp_smcp sParam; glp_init_smcp(&sParam); //-- set control parameters if (lpsolver==1){ //remap of control parameters for simplex method sParam.msg_lev=glpIntParam[0]; // message level // simplex method: primal/dual if (glpIntParam[2]==0) sParam.meth=GLP_PRIMAL; else sParam.meth=GLP_DUALP; // pricing technique if (glpIntParam[3]==0) sParam.pricing=GLP_PT_STD; else sParam.pricing=GLP_PT_PSE; //sParam.r_test not available sParam.tol_bnd=glpRealParam[1]; // primal feasible tollerance sParam.tol_dj=glpRealParam[2]; // dual feasible tollerance sParam.tol_piv=glpRealParam[3]; // pivot tollerance sParam.obj_ll=glpRealParam[4]; // lower limit sParam.obj_ul=glpRealParam[5]; // upper limit // iteration limit if (glpIntParam[5]==-1) sParam.it_lim=INT_MAX; else sParam.it_lim=glpIntParam[5]; // time limit if (glpRealParam[6]==-1) sParam.tm_lim=INT_MAX; else sParam.tm_lim=(int) glpRealParam[6]; sParam.out_frq=glpIntParam[7]; // output frequency sParam.out_dly=(int) glpRealParam[7]; // output delay // presolver if (glpIntParam[16]) sParam.presolve=GLP_ON; else sParam.presolve=GLP_OFF; }else{ for(int i = 0; i < NIntP; i++) lpx_set_int_parm (lp, IParam[i], glpIntParam[i]); for (int i = 0; i < NRealP; i++) lpx_set_real_parm (lp, RParam[i], glpRealParam[i]); } // Choose simplex method ('S') or interior point method ('T') to solve the problem if (lpsolver == 1) method = 'S'; else method = 'T'; int errnum; switch (method){ case 'S': { if (isMIP){ method = 'I'; errnum = lpx_intopt (lp); } else{ errnum = glp_simplex(lp, &sParam); errnum += 100; //this is to avoid ambiguity in the return codes. } } break; case 'T': errnum = lpx_interior(lp); break; default: xassert (method != method); } /* errnum assumes the following results: errnum = 0 <=> No errors errnum = 1 <=> Iteration limit exceeded. errnum = 2 <=> Numerical problems with basis matrix. */ if (errnum == LPX_E_OK || errnum==100){ // Get status and object value if (isMIP) { *status = glp_mip_status (lp); *fmin = glp_mip_obj_val (lp); } else { if (lpsolver == 1) { *status = glp_get_status (lp); *fmin = glp_get_obj_val (lp); } else { *status = glp_ipt_status (lp); *fmin = glp_ipt_obj_val (lp); } } // Get optimal solution (if exists) if (isMIP) { for (int i = 0; i < n; i++) xmin[i] = glp_mip_col_val (lp, i+1); } else { /* Primal values */ for (int i = 0; i < n; i++) { if (lpsolver == 1) xmin[i] = glp_get_col_prim (lp, i+1); else xmin[i] = glp_ipt_col_prim (lp, i+1); } /* Dual values */ for (int i = 0; i < m; i++) { if (lpsolver == 1) lambda[i] = glp_get_row_dual (lp, i+1); else lambda[i] = glp_ipt_row_dual (lp, i+1); } /* Reduced costs */ for (int i = 0; i < glp_get_num_cols (lp); i++) { if (lpsolver == 1) redcosts[i] = glp_get_col_dual (lp, i+1); else redcosts[i] = glp_ipt_col_dual (lp, i+1); } } *time = (clock () - t_start) / CLOCKS_PER_SEC; glp_ulong tpeak; lib_mem_usage(NULL, NULL, NULL, &tpeak); *mem=(double)(4294967296.0 * tpeak.hi + tpeak.lo) / (1024); glp_delete_prob (lp); return 0; } glp_delete_prob (lp); *status = errnum; return errnum; }
int glp_print_ranges(glp_prob *P, int len, const int list[], int flags, const char *fname) { /* print sensitivity analysis report */ glp_file *fp = NULL; GLPROW *row; GLPCOL *col; int m, n, pass, k, t, numb, type, stat, var1, var2, count, page, ret; double lb, ub, slack, coef, prim, dual, value1, value2, coef1, coef2, obj1, obj2; const char *name, *limit; char buf[13+1]; /* sanity checks */ if (P == NULL || P->magic != GLP_PROB_MAGIC) xerror("glp_print_ranges: P = %p; invalid problem object\n", P); m = P->m, n = P->n; if (len < 0) xerror("glp_print_ranges: len = %d; invalid list length\n", len); if (len > 0) { if (list == NULL) xerror("glp_print_ranges: list = %p: invalid parameter\n", list); for (t = 1; t <= len; t++) { k = list[t]; if (!(1 <= k && k <= m+n)) xerror("glp_print_ranges: list[%d] = %d; row/column numb" "er out of range\n", t, k); } } if (flags != 0) xerror("glp_print_ranges: flags = %d; invalid parameter\n", flags); if (fname == NULL) xerror("glp_print_ranges: fname = %p; invalid parameter\n", fname); if (glp_get_status(P) != GLP_OPT) { xprintf("glp_print_ranges: optimal basic solution required\n"); ret = 1; goto done; } if (!glp_bf_exists(P)) { xprintf("glp_print_ranges: basis factorization required\n"); ret = 2; goto done; } /* start reporting */ xprintf("Write sensitivity analysis report to '%s'...\n", fname); fp = glp_open(fname, "w"); if (fp == NULL) { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); ret = 3; goto done; } page = count = 0; for (pass = 1; pass <= 2; pass++) for (t = 1; t <= (len == 0 ? m+n : len); t++) { if (t == 1) count = 0; k = (len == 0 ? t : list[t]); if (pass == 1 && k > m || pass == 2 && k <= m) continue; if (count == 0) { xfprintf(fp, "GLPK %-4s - SENSITIVITY ANALYSIS REPORT%73sPa" "ge%4d\n", glp_version(), "", ++page); xfprintf(fp, "\n"); xfprintf(fp, "%-12s%s\n", "Problem:", P->name == NULL ? "" : P->name); xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", P->obj == NULL ? "" : P->obj, P->obj == NULL ? "" : " = ", P->obj_val, P->dir == GLP_MIN ? "MINimum" : P->dir == GLP_MAX ? "MAXimum" : "???"); xfprintf(fp, "\n"); xfprintf(fp, "%6s %-12s %2s %13s %13s %13s %13s %13s %13s " "%s\n", "No.", pass == 1 ? "Row name" : "Column name", "St", "Activity", pass == 1 ? "Slack" : "Obj coef", "Lower bound", "Activity", "Obj coef", "Obj value at", "Limiting"); xfprintf(fp, "%6s %-12s %2s %13s %13s %13s %13s %13s %13s " "%s\n", "", "", "", "", "Marginal", "Upper bound", "range", "range", "break point", "variable"); xfprintf(fp, "------ ------------ -- ------------- --------" "----- ------------- ------------- ------------- ------" "------- ------------\n"); } if (pass == 1) { numb = k; xassert(1 <= numb && numb <= m); row = P->row[numb]; name = row->name; type = row->type; lb = glp_get_row_lb(P, numb); ub = glp_get_row_ub(P, numb); coef = 0.0; stat = row->stat; prim = row->prim; if (type == GLP_FR) slack = - prim; else if (type == GLP_LO) slack = lb - prim; else if (type == GLP_UP || type == GLP_DB || type == GLP_FX) slack = ub - prim; dual = row->dual; } else { numb = k - m; xassert(1 <= numb && numb <= n); col = P->col[numb]; name = col->name; lb = glp_get_col_lb(P, numb); ub = glp_get_col_ub(P, numb); coef = col->coef; stat = col->stat; prim = col->prim; slack = 0.0; dual = col->dual; } if (stat != GLP_BS) { glp_analyze_bound(P, k, &value1, &var1, &value2, &var2); if (stat == GLP_NF) coef1 = coef2 = coef; else if (stat == GLP_NS) coef1 = -DBL_MAX, coef2 = +DBL_MAX; else if (stat == GLP_NL && P->dir == GLP_MIN || stat == GLP_NU && P->dir == GLP_MAX) coef1 = coef - dual, coef2 = +DBL_MAX; else coef1 = -DBL_MAX, coef2 = coef - dual; if (value1 == -DBL_MAX) { if (dual < -1e-9) obj1 = +DBL_MAX; else if (dual > +1e-9) obj1 = -DBL_MAX; else obj1 = P->obj_val; } else obj1 = P->obj_val + dual * (value1 - prim); if (value2 == +DBL_MAX) { if (dual < -1e-9) obj2 = -DBL_MAX; else if (dual > +1e-9) obj2 = +DBL_MAX; else obj2 = P->obj_val; } else obj2 = P->obj_val + dual * (value2 - prim); } else { glp_analyze_coef(P, k, &coef1, &var1, &value1, &coef2, &var2, &value2); if (coef1 == -DBL_MAX) { if (prim < -1e-9) obj1 = +DBL_MAX; else if (prim > +1e-9) obj1 = -DBL_MAX; else obj1 = P->obj_val; } else obj1 = P->obj_val + (coef1 - coef) * prim; if (coef2 == +DBL_MAX) { if (prim < -1e-9) obj2 = -DBL_MAX; else if (prim > +1e-9) obj2 = +DBL_MAX; else obj2 = P->obj_val; } else obj2 = P->obj_val + (coef2 - coef) * prim; } /*** first line ***/ /* row/column number */ xfprintf(fp, "%6d", numb); /* row/column name */ xfprintf(fp, " %-12.12s", name == NULL ? "" : name); if (name != NULL && strlen(name) > 12) xfprintf(fp, "%s\n%6s %12s", name+12, "", ""); /* row/column status */ xfprintf(fp, " %2s", stat == GLP_BS ? "BS" : stat == GLP_NL ? "NL" : stat == GLP_NU ? "NU" : stat == GLP_NF ? "NF" : stat == GLP_NS ? "NS" : "??"); /* row/column activity */ xfprintf(fp, " %s", format(buf, prim)); /* row slack, column objective coefficient */ xfprintf(fp, " %s", format(buf, k <= m ? slack : coef)); /* row/column lower bound */ xfprintf(fp, " %s", format(buf, lb)); /* row/column activity range */ xfprintf(fp, " %s", format(buf, value1)); /* row/column objective coefficient range */ xfprintf(fp, " %s", format(buf, coef1)); /* objective value at break point */ xfprintf(fp, " %s", format(buf, obj1)); /* limiting variable name */ if (var1 != 0) { if (var1 <= m) limit = glp_get_row_name(P, var1); else limit = glp_get_col_name(P, var1 - m); if (limit != NULL) xfprintf(fp, " %s", limit); } xfprintf(fp, "\n"); /*** second line ***/ xfprintf(fp, "%6s %-12s %2s %13s", "", "", "", ""); /* row/column reduced cost */ xfprintf(fp, " %s", format(buf, dual)); /* row/column upper bound */ xfprintf(fp, " %s", format(buf, ub)); /* row/column activity range */ xfprintf(fp, " %s", format(buf, value2)); /* row/column objective coefficient range */ xfprintf(fp, " %s", format(buf, coef2)); /* objective value at break point */ xfprintf(fp, " %s", format(buf, obj2)); /* limiting variable name */ if (var2 != 0) { if (var2 <= m) limit = glp_get_row_name(P, var2); else limit = glp_get_col_name(P, var2 - m); if (limit != NULL) xfprintf(fp, " %s", limit); } xfprintf(fp, "\n"); xfprintf(fp, "\n"); /* print 10 items per page */ count = (count + 1) % 10; } xfprintf(fp, "End of report\n"); #if 0 /* FIXME */ xfflush(fp); #endif if (glp_ioerr(fp)) { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); ret = 4; goto done; } ret = 0; done: if (fp != NULL) glp_close(fp); return ret; }
/** * Solves the LP problem * * @param mlp the MLP Handle * @param s_ctx context to return results * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ static int mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx) { int res; struct GNUNET_TIME_Relative duration; struct GNUNET_TIME_Absolute end; struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get(); /* LP presolver? * Presolver is required if the problem was modified and an existing * valid basis is now invalid */ if (mlp->presolver_required == GNUNET_YES) mlp->control_param_lp.presolve = GLP_ON; else mlp->control_param_lp.presolve = GLP_OFF; /* Solve LP problem to have initial valid solution */ lp_solv: res = glp_simplex(mlp->prob, &mlp->control_param_lp); if (res == 0) { /* The LP problem instance has been successfully solved. */ } else if (res == GLP_EITLIM) { /* simplex iteration limit has been exceeded. */ // TODO Increase iteration limit? } else if (res == GLP_ETMLIM) { /* Time limit has been exceeded. */ // TODO Increase time limit? } else { /* Problem was ill-defined, retry with presolver */ if (mlp->presolver_required == GNUNET_NO) { mlp->presolver_required = GNUNET_YES; goto lp_solv; } else { /* Problem was ill-defined, no way to handle that */ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-mlp", "Solving LP problem failed: %i %s\n", res, mlp_solve_to_string(res)); return GNUNET_SYSERR; } } end = GNUNET_TIME_absolute_get (); duration = GNUNET_TIME_absolute_get_difference (start, end); mlp->lp_solved++; mlp->lp_total_duration =+ duration.rel_value; s_ctx->lp_duration = duration; GNUNET_STATISTICS_update (mlp->stats,"# LP problem solved", 1, GNUNET_NO); GNUNET_STATISTICS_set (mlp->stats,"# LP execution time (ms)", duration.rel_value, GNUNET_NO); GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average (ms)", mlp->lp_total_duration / mlp->lp_solved, GNUNET_NO); /* Analyze problem status */ res = glp_get_status (mlp->prob); switch (res) { /* solution is optimal */ case GLP_OPT: /* solution is feasible */ case GLP_FEAS: break; /* Problem was ill-defined, no way to handle that */ default: GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-mlp", "Solving LP problem failed, no solution: %s\n", mlp_status_to_string(res)); return GNUNET_SYSERR; break; } /* solved sucessfully, no presolver required next time */ mlp->presolver_required = GNUNET_NO; return GNUNET_OK; }
static PyObject* LPX_solver_integer(LPXObject *self, PyObject *args, PyObject *keywds) { #if GLPK_VERSION(4, 20) PyObject *callback=NULL; struct mip_callback_object*info=NULL; glp_iocp cp; glp_init_iocp(&cp); cp.msg_lev = GLP_MSG_OFF; // Map the keyword arguments to the appropriate entries. static char *kwlist[] = {"msg_lev", "br_tech", "bt_tech", #if GLPK_VERSION(4, 21) "pp_tech", #endif // GLPK_VERSION(4, 21) #if GLPK_VERSION(4, 24) "gmi_cuts", #endif // GLPK_VERSION(4, 24) #if GLPK_VERSION(4, 23) "mir_cuts", "mip_gap", #endif // GLPK_VERSION(4, 23) #if GLPK_VERSION(4, 32) "cov_cuts", "clq_cuts", "presolve", "binarize", #endif // GLPK_VERSION(4, 32) #if GLPK_VERSION(4, 37) "fp_heur", #endif // GLPK_VERSION(4, 37) "tol_int", "tol_obj", "tm_lim", "out_frq", "out_dly", "callback", //"cb_info", "cb_size", NULL}; if (!PyArg_ParseTupleAndKeywords (args, keywds, "|iii" #if GLPK_VERSION(4, 21) "i" #endif // GLPK_VERSION(4, 21) #if GLPK_VERSION(4, 24) "i" #endif // GLPK_VERSION(4, 24) #if GLPK_VERSION(4, 23) "ii" #endif // GLPK_VERSION(4, 23) #if GLPK_VERSION(4, 32) "iiii" #endif // GLPK_VERSION(4, 32) #if GLPK_VERSION(4, 37) "i" #endif // GLPK_VERSION(4, 37) "ddiiiO", kwlist, &cp.msg_lev, &cp.br_tech, &cp.bt_tech, #if GLPK_VERSION(4, 21) &cp.pp_tech, #endif // GLPK_VERSION(4, 21) #if GLPK_VERSION(4, 24) &cp.gmi_cuts, #endif // GLPK_VERSION(4, 24) #if GLPK_VERSION(4, 23) &cp.mir_cuts, &cp.mip_gap, #endif // GLPK_VERSION(4, 23) #if GLPK_VERSION(4, 32) &cp.cov_cuts, &cp.clq_cuts, &cp.presolve, &cp.binarize, #endif // GLPK_VERSION(4, 32) #if GLPK_VERSION(4, 37) &cp.fp_heur, #endif // GLPK_VERSION(4, 37) &cp.tol_int, &cp.tol_obj, &cp.tm_lim, &cp.out_frq, &cp.out_dly, &callback)) { return NULL; } #if GLPK_VERSION(4, 24) cp.gmi_cuts = cp.gmi_cuts ? GLP_ON : GLP_OFF; #endif // GLPK_VERSION(4, 24) #if GLPK_VERSION(4, 23) cp.mir_cuts = cp.mir_cuts ? GLP_ON : GLP_OFF; #endif // GLPK_VERSION(4, 23) #if GLPK_VERSION(4, 32) cp.cov_cuts = cp.cov_cuts ? GLP_ON : GLP_OFF; cp.clq_cuts = cp.clq_cuts ? GLP_ON : GLP_OFF; cp.presolve = cp.presolve ? GLP_ON : GLP_OFF; cp.binarize = cp.binarize ? GLP_ON : GLP_OFF; #endif // GLPK_VERSION(4, 32) #if GLPK_VERSION(4, 37) cp.fp_heur = cp.fp_heur ? GLP_ON : GLP_OFF; #endif // GLPK_VERSION(4, 32) // Do checking on the various entries. #if GLPK_VERSION(4, 32) if (!cp.presolve && glp_get_status(LP) != GLP_OPT) { PyErr_SetString(PyExc_RuntimeError, "integer solver requires " "use of presolver or existing optimal basic solution"); return NULL; } #else if (glp_get_status(LP) != GLP_OPT) { PyErr_SetString(PyExc_RuntimeError, "integer solver requires " "existing optimal basic solution"); return NULL; } #endif switch (cp.msg_lev) { case GLP_MSG_OFF: case GLP_MSG_ERR: case GLP_MSG_ON: case GLP_MSG_ALL: break; default: PyErr_SetString (PyExc_ValueError, "invalid value for msg_lev (LPX.MSG_* are valid values)"); return NULL; } switch (cp.br_tech) { case GLP_BR_FFV: case GLP_BR_LFV: case GLP_BR_MFV: case GLP_BR_DTH: break; default: PyErr_SetString (PyExc_ValueError, "invalid value for br_tech (LPX.BR_* are valid values)"); return NULL; } switch (cp.bt_tech) { case GLP_BT_DFS: case GLP_BT_BFS: case GLP_BT_BLB: case GLP_BT_BPH: break; default: PyErr_SetString (PyExc_ValueError, "invalid value for bt_tech (LPX.BT_* are valid values)"); return NULL; } #if GLPK_VERSION(4, 21) switch (cp.pp_tech) { case GLP_PP_NONE: case GLP_PP_ROOT: case GLP_PP_ALL: break; default: PyErr_SetString (PyExc_ValueError, "invalid value for pp_tech (LPX.PP_* are valid values)"); return NULL; } #endif // GLPK_VERSION(4, 21) if (cp.tol_int<=0 || cp.tol_int>=1) { PyErr_SetString(PyExc_ValueError, "tol_int must obey 0<tol_int<1"); return NULL; } if (cp.tol_obj<=0 || cp.tol_obj>=1) { PyErr_SetString(PyExc_ValueError, "tol_obj must obey 0<tol_obj<1"); return NULL; } if (cp.tm_lim<0) { PyErr_SetString(PyExc_ValueError, "tm_lim must be non-negative"); return NULL; } if (cp.out_frq<=0) { PyErr_SetString(PyExc_ValueError, "out_frq must be positive"); return NULL; } if (cp.out_dly<0) { PyErr_SetString(PyExc_ValueError, "out_dly must be non-negative"); return NULL; } #if GLPK_VERSION(4, 23) if (cp.mip_gap<0) { PyErr_SetString(PyExc_ValueError, "mip_gap must be non-negative"); return NULL; } #endif int retval; if (callback != NULL && callback != Py_None) { info = (struct mip_callback_object*) malloc(sizeof(struct mip_callback_object)); info->callback = callback; info->py_lp = self; cp.cb_info = info; cp.cb_func = mip_callback; } retval = glp_intopt(LP, &cp); if (info) free(info); if (PyErr_Occurred()) { // This should happen only if there was a problem within the // callback function, or if the callback was not appropriate. return NULL; } if (retval!=GLP_EBADB && retval!=GLP_ESING && retval!=GLP_ECOND && retval!=GLP_EBOUND && retval!=GLP_EFAIL) self->last_solver = 2; return glpsolver_retval_to_message(retval); #else int retval = lpx_integer(LP); if (retval!=LPX_E_FAULT) self->last_solver = 2; return solver_retval_to_message(retval); #endif // GLPK_VERSION(4, 20) }
int max_flow_lp(int nn, int ne, const int beg[/*1+ne*/], const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, int x[/*1+ne*/]) { glp_prob *lp; glp_smcp smcp; int i, k, nz, flow, *rn, *cn; double temp, *aa; /* create LP problem instance */ lp = glp_create_prob(); /* create LP rows; i-th row is the conservation condition of the * flow at i-th node, i = 1, ..., nn */ glp_add_rows(lp, nn); for (i = 1; i <= nn; i++) glp_set_row_bnds(lp, i, GLP_FX, 0.0, 0.0); /* create LP columns; k-th column is the elementary flow thru * k-th edge, k = 1, ..., ne; the last column with the number * ne+1 is the total flow through the network, which goes along * a dummy feedback edge from the sink to the source */ glp_add_cols(lp, ne+1); for (k = 1; k <= ne; k++) { xassert(cap[k] > 0); glp_set_col_bnds(lp, k, GLP_DB, -cap[k], +cap[k]); } glp_set_col_bnds(lp, ne+1, GLP_FR, 0.0, 0.0); /* build the constraint matrix; structurally this matrix is the * incidence matrix of the network, so each its column (including * the last column for the dummy edge) has exactly two non-zero * entries */ rn = xalloc(1+2*(ne+1), sizeof(int)); cn = xalloc(1+2*(ne+1), sizeof(int)); aa = xalloc(1+2*(ne+1), sizeof(double)); nz = 0; for (k = 1; k <= ne; k++) { /* x[k] > 0 means the elementary flow thru k-th edge goes from * node beg[k] to node end[k] */ nz++, rn[nz] = beg[k], cn[nz] = k, aa[nz] = -1.0; nz++, rn[nz] = end[k], cn[nz] = k, aa[nz] = +1.0; } /* total flow thru the network goes from the sink to the source * along the dummy feedback edge */ nz++, rn[nz] = t, cn[nz] = ne+1, aa[nz] = -1.0; nz++, rn[nz] = s, cn[nz] = ne+1, aa[nz] = +1.0; /* check the number of non-zero entries */ xassert(nz == 2*(ne+1)); /* load the constraint matrix into the LP problem object */ glp_load_matrix(lp, nz, rn, cn, aa); xfree(rn); xfree(cn); xfree(aa); /* objective function is the total flow through the network to * be maximized */ glp_set_obj_dir(lp, GLP_MAX); glp_set_obj_coef(lp, ne + 1, 1.0); /* solve LP instance with the (primal) simplex method */ glp_term_out(0); glp_adv_basis(lp, 0); glp_term_out(1); glp_init_smcp(&smcp); smcp.msg_lev = GLP_MSG_ON; smcp.out_dly = 5000; xassert(glp_simplex(lp, &smcp) == 0); xassert(glp_get_status(lp) == GLP_OPT); /* obtain optimal elementary flows thru edges of the network */ /* (note that the constraint matrix is unimodular and the data * are integral, so all elementary flows in basic solution should * also be integral) */ for (k = 1; k <= ne; k++) { temp = glp_get_col_prim(lp, k); x[k] = (int)floor(temp + .5); xassert(fabs(x[k] - temp) <= 1e-6); } /* obtain the maximum flow thru the original network which is the * flow thru the dummy feedback edge */ temp = glp_get_col_prim(lp, ne+1); flow = (int)floor(temp + .5); xassert(fabs(flow - temp) <= 1e-6); /* delete LP problem instance */ glp_delete_prob(lp); /* return to the calling program */ return flow; }
int glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn, double *a, double *b, char *ctype, int *freeLB, double *lb, int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, int save_pb, char *save_filename, char *filetype, double *xmin, double *fmin, double *status, double *lambda, double *redcosts, double *time, double *mem) { int typx = 0; int method; clock_t t_start = clock(); //Redirect standard output if (glpIntParam[0] > 1) glp_term_hook (glpk_print_hook, NULL); else glp_term_hook (NULL, NULL); //-- Create an empty LP/MILP object LPX *lp = lpx_create_prob (); //-- Set the sense of optimization if (sense == 1) glp_set_obj_dir (lp, GLP_MIN); else glp_set_obj_dir (lp, GLP_MAX); //-- Define the number of unknowns and their domains. glp_add_cols (lp, n); for (int i = 0; i < n; i++) { //-- Define type of the structural variables if (! freeLB[i] && ! freeUB[i]) { if ( lb[i] == ub[i] ) glp_set_col_bnds (lp, i+1, GLP_FX, lb[i], ub[i]); else glp_set_col_bnds (lp, i+1, GLP_DB, lb[i], ub[i]); } else { if (! freeLB[i] && freeUB[i]) glp_set_col_bnds (lp, i+1, GLP_LO, lb[i], ub[i]); else { if (freeLB[i] && ! freeUB[i]) glp_set_col_bnds (lp, i+1, GLP_UP, lb[i], ub[i]); else glp_set_col_bnds (lp, i+1, GLP_FR, lb[i], ub[i]); } } // -- Set the objective coefficient of the corresponding // -- structural variable. No constant term is assumed. glp_set_obj_coef(lp,i+1,c[i]); if (isMIP) glp_set_col_kind (lp, i+1, vartype[i]); } glp_add_rows (lp, m); for (int i = 0; i < m; i++) { /* If the i-th row has no lower bound (types F,U), the corrispondent parameter will be ignored. If the i-th row has no upper bound (types F,L), the corrispondent parameter will be ignored. If the i-th row is of S type, the i-th LB is used, but the i-th UB is ignored. */ switch (ctype[i]) { case 'F': typx = GLP_FR; break; // upper bound case 'U': typx = GLP_UP; break; // lower bound case 'L': typx = GLP_LO; break; // fixed constraint case 'S': typx = GLP_FX; break; // double-bounded variable case 'D': typx = GLP_DB; break; } if ( typx == GLP_DB && -b[i] < b[i]) { glp_set_row_bnds (lp, i+1, typx, -b[i], b[i]); } else if(typx == GLP_DB && -b[i] == b[i]) { glp_set_row_bnds (lp, i+1, GLP_FX, b[i], b[i]); } else { // this should be glp_set_row_bnds (lp, i+1, typx, -b[i], b[i]); glp_set_row_bnds (lp, i+1, typx, b[i], b[i]); } } // Load constraint matrix A glp_load_matrix (lp, nz, rn, cn, a); // Save problem if (save_pb) { if (!strcmp(filetype,"cplex")){ if (glp_write_lp (lp, NULL, save_filename) != 0) { mexErrMsgTxt("glpk: unable to write the problem"); longjmp (mark, -1); } }else{ if (!strcmp(filetype,"fixedmps")){ if (glp_write_mps (lp, GLP_MPS_DECK, NULL, save_filename) != 0) { mexErrMsgTxt("glpk: unable to write the problem"); longjmp (mark, -1); } }else{ if (!strcmp(filetype,"freemps")){ if (glp_write_mps (lp, GLP_MPS_FILE, NULL, save_filename) != 0) { mexErrMsgTxt("glpk: unable to write the problem"); longjmp (mark, -1); } }else{// plain text if (lpx_print_prob (lp, save_filename) != 0) { mexErrMsgTxt("glpk: unable to write the problem"); longjmp (mark, -1); } } } } } //-- scale the problem data (if required) if (! glpIntParam[16] || lpsolver != 1) { switch ( glpIntParam[1] ) { case ( 0 ): glp_scale_prob( lp, GLP_SF_SKIP ); break; case ( 1 ): glp_scale_prob( lp, GLP_SF_GM ); break; case ( 2 ): glp_scale_prob( lp, GLP_SF_EQ ); break; case ( 3 ): glp_scale_prob( lp, GLP_SF_AUTO ); break; case ( 4 ): glp_scale_prob( lp, GLP_SF_2N ); break; default : mexErrMsgTxt("glpk: unrecognized scaling option"); longjmp (mark, -1); } } else { /* do nothing? or unscale? glp_unscale_prob( lp ); */ } //-- build advanced initial basis (if required) if (lpsolver == 1 && ! glpIntParam[16]) glp_adv_basis (lp, 0); glp_smcp sParam; glp_init_smcp(&sParam); //-- set control parameters for simplex/exact method if (lpsolver == 1 || lpsolver == 3){ //remap of control parameters for simplex method sParam.msg_lev=glpIntParam[0]; // message level // simplex method: primal/dual switch ( glpIntParam[2] ) { case 0: sParam.meth=GLP_PRIMAL; break; case 1: sParam.meth=GLP_DUAL; break; case 2: sParam.meth=GLP_DUALP; break; default: mexErrMsgTxt("glpk: unrecognized primal/dual method"); longjmp (mark, -1); } // pricing technique if (glpIntParam[3]==0) sParam.pricing=GLP_PT_STD; else sParam.pricing=GLP_PT_PSE; // ratio test if (glpIntParam[20]==0) sParam.r_test = GLP_RT_STD; else sParam.r_test=GLP_RT_HAR; //tollerances sParam.tol_bnd=glpRealParam[1]; // primal feasible tollerance sParam.tol_dj=glpRealParam[2]; // dual feasible tollerance sParam.tol_piv=glpRealParam[3]; // pivot tollerance sParam.obj_ll=glpRealParam[4]; // lower limit sParam.obj_ul=glpRealParam[5]; // upper limit // iteration limit if (glpIntParam[5]==-1) sParam.it_lim=INT_MAX; else sParam.it_lim=glpIntParam[5]; // time limit if (glpRealParam[6]==-1) sParam.tm_lim=INT_MAX; else sParam.tm_lim=(int) glpRealParam[6]; sParam.out_frq=glpIntParam[7]; // output frequency sParam.out_dly=(int) glpRealParam[7]; // output delay // presolver if (glpIntParam[16]) sParam.presolve=GLP_ON; else sParam.presolve=GLP_OFF; }else{ for(int i = 0; i < NIntP; i++) { // skip assinging ratio test or if ( i == 18 || i == 20) continue; lpx_set_int_parm (lp, IParam[i], glpIntParam[i]); } for (int i = 0; i < NRealP; i++) { lpx_set_real_parm (lp, RParam[i], glpRealParam[i]); } } //set MIP params if MIP.... glp_iocp iParam; glp_init_iocp(&iParam); if ( isMIP ){ method = 'I'; switch (glpIntParam[0]) { //message level case 0: iParam.msg_lev = GLP_MSG_OFF; break; case 1: iParam.msg_lev = GLP_MSG_ERR; break; case 2: iParam.msg_lev = GLP_MSG_ON; break; case 3: iParam.msg_lev = GLP_MSG_ALL; break; default: mexErrMsgTxt("glpk: msg_lev bad param"); } switch (glpIntParam[14]) { //branching param case 0: iParam.br_tech = GLP_BR_FFV; break; case 1: iParam.br_tech = GLP_BR_LFV; break; case 2: iParam.br_tech = GLP_BR_MFV; break; case 3: iParam.br_tech = GLP_BR_DTH; break; default: mexErrMsgTxt("glpk: branch bad param"); } switch (glpIntParam[15]) { //backtracking heuristic case 0: iParam.bt_tech = GLP_BT_DFS; break; case 1: iParam.bt_tech = GLP_BT_BFS; break; case 2: iParam.bt_tech = GLP_BT_BLB; break; case 3: iParam.bt_tech = GLP_BT_BPH; break; default: mexErrMsgTxt("glpk: backtrack bad param"); } if ( glpRealParam[8] > 0.0 && glpRealParam[8] < 1.0 ) iParam.tol_int = glpRealParam[8]; // absolute tolorence else mexErrMsgTxt("glpk: tolint must be between 0 and 1"); iParam.tol_obj = glpRealParam[9]; // relative tolarence iParam.mip_gap = glpRealParam[10]; // realative gap tolerance // set time limit for mip if ( glpRealParam[6] < 0.0 || glpRealParam[6] > 1e6 ) iParam.tm_lim = INT_MAX; else iParam.tm_lim = (int)(1000.0 * glpRealParam[6] ); // Choose Cutsets for mip // shut all cuts off, then start over.... iParam.gmi_cuts = GLP_OFF; iParam.mir_cuts = GLP_OFF; iParam.cov_cuts = GLP_OFF; iParam.clq_cuts = GLP_OFF; switch( glpIntParam[17] ) { case 0: break; case 1: iParam.gmi_cuts = GLP_ON; break; case 2: iParam.mir_cuts = GLP_ON; break; case 3: iParam.cov_cuts = GLP_ON; break; case 4: iParam.clq_cuts = GLP_ON; break; case 5: iParam.clq_cuts = GLP_ON; iParam.gmi_cuts = GLP_ON; iParam.mir_cuts = GLP_ON; iParam.cov_cuts = GLP_ON; iParam.clq_cuts = GLP_ON; break; default: mexErrMsgTxt("glpk: cutset bad param"); } switch( glpIntParam[18] ) { // pre-processing for mip case 0: iParam.pp_tech = GLP_PP_NONE; break; case 1: iParam.pp_tech = GLP_PP_ROOT; break; case 2: iParam.pp_tech = GLP_PP_ALL; break; default: mexErrMsgTxt("glpk: pprocess bad param"); } if (glpIntParam[16]) iParam.presolve=GLP_ON; else iParam.presolve=GLP_OFF; if (glpIntParam[19]) iParam.binarize = GLP_ON; else iParam.binarize = GLP_OFF; } else { /* Choose simplex method ('S') or interior point method ('T') or Exact method ('E') to solve the problem */ switch (lpsolver) { case 1: method = 'S'; break; case 2: method = 'T'; break; case 3: method = 'E'; break; default: mexErrMsgTxt("glpk: lpsolver != lpsolver"); longjmp (mark, -1); } } // now run the problem... int errnum = 0; switch (method) { case 'I': errnum = glp_intopt( lp, &iParam ); errnum += 200; //this is to avoid ambiguity in the return codes. break; case 'S': errnum = glp_simplex(lp, &sParam); errnum += 100; //this is to avoid ambiguity in the return codes. break; case 'T': errnum = glp_interior(lp, NULL ); errnum += 300; //this is to avoid ambiguity in the return codes. break; case 'E': errnum = glp_exact(lp, &sParam); errnum += 100; //this is to avoid ambiguity in the return codes. break; default: /*xassert (method != method); */ mexErrMsgTxt("glpk: method != method"); longjmp (mark, -1); } if (errnum==100 || errnum==200 || errnum==300 || errnum==106 || errnum==107 || errnum==108 || errnum==109 || errnum==209 || errnum==214 || errnum==308) { // Get status and object value if (isMIP) { *status = glp_mip_status (lp); *fmin = glp_mip_obj_val (lp); } else { if (lpsolver == 1 || lpsolver == 3) { *status = glp_get_status (lp); *fmin = glp_get_obj_val (lp); } else { *status = glp_ipt_status (lp); *fmin = glp_ipt_obj_val (lp); } } // Get optimal solution (if exists) if (isMIP) { for (int i = 0; i < n; i++) xmin[i] = glp_mip_col_val (lp, i+1); } else { /* Primal values */ for (int i = 0; i < n; i++) { if (lpsolver == 1 || lpsolver == 3) xmin[i] = glp_get_col_prim (lp, i+1); else xmin[i] = glp_ipt_col_prim (lp, i+1); } /* Dual values */ for (int i = 0; i < m; i++) { if (lpsolver == 1 || lpsolver == 3) lambda[i] = glp_get_row_dual (lp, i+1); else lambda[i] = glp_ipt_row_dual (lp, i+1); } /* Reduced costs */ for (int i = 0; i < glp_get_num_cols (lp); i++) { if (lpsolver == 1 || lpsolver == 3) redcosts[i] = glp_get_col_dual (lp, i+1); else redcosts[i] = glp_ipt_col_dual (lp, i+1); } } *time = (clock () - t_start) / CLOCKS_PER_SEC; size_t tpeak; glp_mem_usage(NULL, NULL, NULL, &tpeak); *mem=((double) tpeak) / (1024); lpx_delete_prob(lp); return 0; } else { // printf("errnum is %d\n", errnum); } lpx_delete_prob(lp); /* this shouldn't be nessiary with glp_deleted_prob, but try it if we have weird behavior again... */ glp_free_env(); *status = errnum; return errnum; }
static int preprocess_and_solve_mip(glp_prob *P, const glp_iocp *parm) { /* solve MIP using the preprocessor */ ENV *env = get_env_ptr(); int term_out = env->term_out; NPP *npp; glp_prob *mip = NULL; glp_bfcp bfcp; glp_smcp smcp; int ret; if (parm->msg_lev >= GLP_MSG_ALL) xprintf("Preprocessing...\n"); /* create preprocessor workspace */ npp = npp_create_wksp(); /* load original problem into the preprocessor workspace */ npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF); /* process MIP prior to applying the branch-and-bound method */ if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; ret = npp_integer(npp, parm); env->term_out = term_out; if (ret == 0) ; else if (ret == GLP_ENOPFS) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n"); } else if (ret == GLP_ENODFS) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION\n"); } else xassert(ret != ret); if (ret != 0) goto done; /* build transformed MIP */ mip = glp_create_prob(); npp_build_prob(npp, mip); /* if the transformed MIP is empty, it has empty solution, which is optimal */ if (mip->m == 0 && mip->n == 0) { mip->mip_stat = GLP_OPT; mip->mip_obj = mip->c0; if (parm->msg_lev >= GLP_MSG_ALL) { xprintf("Objective value = %17.9e\n", mip->mip_obj); xprintf("INTEGER OPTIMAL SOLUTION FOUND BY MIP PREPROCESSOR" "\n"); } goto post; } /* display some statistics */ if (parm->msg_lev >= GLP_MSG_ALL) { int ni = glp_get_num_int(mip); int nb = glp_get_num_bin(mip); char s[50]; xprintf("%d row%s, %d column%s, %d non-zero%s\n", mip->m, mip->m == 1 ? "" : "s", mip->n, mip->n == 1 ? "" : "s", mip->nnz, mip->nnz == 1 ? "" : "s"); if (nb == 0) strcpy(s, "none of"); else if (ni == 1 && nb == 1) strcpy(s, ""); else if (nb == 1) strcpy(s, "one of"); else if (nb == ni) strcpy(s, "all of"); else sprintf(s, "%d of", nb); xprintf("%d integer variable%s, %s which %s binary\n", ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); } /* inherit basis factorization control parameters */ glp_get_bfcp(P, &bfcp); glp_set_bfcp(mip, &bfcp); /* scale the transformed problem */ if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; glp_scale_prob(mip, GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP); env->term_out = term_out; /* build advanced initial basis */ if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; glp_adv_basis(mip, 0); env->term_out = term_out; /* solve initial LP relaxation */ if (parm->msg_lev >= GLP_MSG_ALL) xprintf("Solving LP relaxation...\n"); glp_init_smcp(&smcp); smcp.msg_lev = parm->msg_lev; mip->it_cnt = P->it_cnt; ret = glp_simplex(mip, &smcp); P->it_cnt = mip->it_cnt; if (ret != 0) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_intopt: cannot solve LP relaxation\n"); ret = GLP_EFAIL; goto done; } /* check status of the basic solution */ ret = glp_get_status(mip); if (ret == GLP_OPT) ret = 0; else if (ret == GLP_NOFEAS) ret = GLP_ENOPFS; else if (ret == GLP_UNBND) ret = GLP_ENODFS; else xassert(ret != ret); if (ret != 0) goto done; /* solve the transformed MIP */ mip->it_cnt = P->it_cnt; #if 0 /* 11/VII-2013 */ ret = solve_mip(mip, parm); #else if (parm->use_sol) { mip->mip_stat = P->mip_stat; mip->mip_obj = P->mip_obj; } ret = solve_mip(mip, parm, P, npp); #endif P->it_cnt = mip->it_cnt; /* only integer feasible solution can be postprocessed */ if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS)) { P->mip_stat = mip->mip_stat; goto done; } /* postprocess solution from the transformed MIP */ post: npp_postprocess(npp, mip); /* the transformed MIP is no longer needed */ glp_delete_prob(mip), mip = NULL; /* store solution to the original problem */ npp_unload_sol(npp, P); done: /* delete the transformed MIP, if it exists */ if (mip != NULL) glp_delete_prob(mip); /* delete preprocessor workspace */ npp_delete_wksp(npp); return ret; }
bool glpk_wrapper::is_sat() { if (solver_type == SIMPLEX || solver_type == EXACT) { int status = glp_get_status(lp); if (status == GLP_UNDEF || changed) { glp_smcp parm; glp_init_smcp(&parm); parm.msg_lev = GLP_MSG_OFF; // always try first the normal simple (get close to an optimal solution in double precision) int solved = glp_simplex(lp, &parm); // TODO(dzufferey) should we always fall back on exact when the normal simplex failed ? if (solver_type == EXACT || solved != 0) { solved = glp_exact(lp, &parm); } if (solved != 0) { switch (solved) { case GLP_EBADB: throw std::runtime_error("GLPK simplex failed: GLP_EBADB"); case GLP_ESING: throw std::runtime_error("GLPK simplex failed: GLP_ESING"); case GLP_ECOND: throw std::runtime_error("GLPK simplex failed: GLP_ECOND"); case GLP_EBOUND: throw std::runtime_error("GLPK simplex failed: GLP_EBOUND"); case GLP_EFAIL: throw std::runtime_error("GLPK simplex failed: GLP_EFAIL"); case GLP_EOBJLL: throw std::runtime_error("GLPK simplex failed: GLP_EOBJLL"); case GLP_EOBJUL: throw std::runtime_error("GLPK simplex failed: GLP_EOBJUL"); case GLP_EITLIM: throw std::runtime_error("GLPK simplex failed: GLP_EITLIM"); case GLP_ETMLIM: throw std::runtime_error("GLPK simplex failed: GLP_ETMLIM"); case GLP_ENOPFS: throw std::runtime_error("GLPK simplex failed: GLP_ENOPFS"); case GLP_ENODFS: throw std::runtime_error("GLPK simplex failed: GLP_ENODFS"); default: throw std::runtime_error("GLPK simplex failed"); } } status = glp_get_status(lp); changed = false; } return (status == GLP_OPT || status == GLP_FEAS || status == GLP_UNBND); } else { assert(solver_type == INTERIOR); int status = glp_ipt_status(lp); if (status == GLP_UNDEF || changed) { glp_iptcp parm; glp_init_iptcp(&parm); parm.msg_lev = GLP_MSG_OFF; int solved = glp_interior(lp, &parm); if (solved != 0) { switch (solved) { case GLP_EFAIL: throw std::runtime_error("GLPK interior-point failed: GLP_EFAIL"); case GLP_ENOCVG: throw std::runtime_error("GLPK interior-point failed: GLP_ENOCVG"); case GLP_EOBJUL: throw std::runtime_error("GLPK interior-point failed: GLP_EOBJUL"); case GLP_EITLIM: throw std::runtime_error("GLPK interior-point failed: GLP_EITLIM"); case GLP_EINSTAB: throw std::runtime_error("GLPK interior-point failed: GLP_EINSTAB"); default: throw std::runtime_error("GLPK interior-point failed"); } } status = glp_ipt_status(lp); changed = false; } return status == GLP_OPT; } }