int main(void) { glp_prob *lp; int ia[1+1000], ja[1+1000]; double ar[1+1000], z, x1, x2, x3; s1: lp = glp_create_prob(); s2: glp_set_prob_name(lp, "sample"); s3: glp_set_obj_dir(lp, GLP_MAX); s4: glp_add_rows(lp, 3); s5: glp_set_row_name(lp, 1, "p"); s6: glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100.0); s7: glp_set_row_name(lp, 2, "q"); s8: glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 600.0); s9: glp_set_row_name(lp, 3, "r"); s10: glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 300.0); s11: glp_add_cols(lp, 3); s12: glp_set_col_name(lp, 1, "x1"); s13: glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0); s14: glp_set_obj_coef(lp, 1, 10.0); s15: glp_set_col_name(lp, 2, "x2"); s16: glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0); s17: glp_set_obj_coef(lp, 2, 6.0); s18: glp_set_col_name(lp, 3, "x3"); s19: glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0); s20: glp_set_obj_coef(lp, 3, 4.0); s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ s30: glp_load_matrix(lp, 9, ia, ja, ar); s31: glp_simplex(lp, NULL); s32: z = glp_get_obj_val(lp); s33: x1 = glp_get_col_prim(lp, 1); s34: x2 = glp_get_col_prim(lp, 2); s35: x3 = glp_get_col_prim(lp, 3); s36: printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g\n", z, x1, x2, x3); s37: glp_delete_prob(lp); return 0; }
double CMyProblem::RealResult() { char buff[256]; int i=1; int j=1; double value; int add; int result=0; int col_num=glp_find_col(lp,GenerateColName(buff, "x", i, j)); while( col_num ) { value = glp_get_col_prim(lp,col_num); if ( abs(1.0-value)<AVAIL_ERROR ) { add=j*w[i-1]; } j++; col_num=glp_find_col(lp,GenerateColName(buff, "x", i, j)); if (!col_num) { result+=add; i++; j=1; col_num=glp_find_col(lp,GenerateColName(buff, "x", i, j)); } } return result; }
void printResult(glp_prob * Prob, FILE * out) { int i; char buf[AUXSIZE]; glp_smcp * param = malloc(sizeof(glp_smcp)); glp_init_smcp(param); param->msg_lev = GLP_MSG_ERR; param->presolve = GLP_ON; int solution[MAXSIZE]; for( i = 0 ; i < n ; ++i ) solution[planes[i].pos] = i; mapSolution(Prob,solution); glp_simplex(Prob,param); if( simpleOutput ) { time(&final); fprintf(out,"%i & %i \\\\ \n",(int)glp_get_obj_val(Prob),(int)difftime(final,initial)); return; } fprintf(out,"Best found solution's value: %lf\n\n",glp_get_obj_val(Prob)); double time; for( i = 0 ; i < n ; ++i ) { sprintf(buf,"x%i",solution[i]); time = glp_get_col_prim(Prob, glp_find_col(Prob, buf)); fprintf(out,"The %i-th airplane to arrive is airplane %i, at the time %lf\n", i+1,solution[i]+1,time); } }
void glpk_wrapper::get_solution(box & b) { assert(is_sat()); for (unsigned int i = 0; i < b.size(); i++) { if (solver_type == SIMPLEX || solver_type == EXACT) { b[i] = glp_get_col_prim(lp, i+1); } else { assert(solver_type == INTERIOR); b[i] = glp_ipt_col_prim(lp, i+1); } } }
static int branch_first(glp_tree *T, int *_next) { int j, next; double beta; /* choose the column to branch on */ for (j = 1; j <= T->n; j++) if (T->non_int[j]) break; xassert(1 <= j && j <= T->n); /* select the branch to be solved next */ beta = glp_get_col_prim(T->mip, j); if (beta - floor(beta) < ceil(beta) - beta) next = GLP_DN_BRNCH; else next = GLP_UP_BRNCH; *_next = next; return j; }
static int branch_mostf(glp_tree *T, int *_next) { int j, jj, next; double beta, most, temp; /* choose the column to branch on */ jj = 0, most = DBL_MAX; for (j = 1; j <= T->n; j++) { if (T->non_int[j]) { beta = glp_get_col_prim(T->mip, j); temp = floor(beta) + 0.5; if (most > fabs(beta - temp)) { jj = j, most = fabs(beta - temp); if (beta < temp) next = GLP_DN_BRNCH; else next = GLP_UP_BRNCH; } } } *_next = next; return jj; }
inline void PrintSolArray(glp_prob* lp, char* name, ostream &out, bool integer=false) { out << name << endl; char buff[256]; int i=1; int j=1; double value; int col_num=glp_find_col(lp,GenerateColName(buff, name, i, j)); while( col_num ) { if (!integer) { value = glp_get_col_prim(lp,col_num); //проверка иксов на целочисленность if ((strcmp(name,"x")==0)&&(IsNotBinary(value))) { out<<"!!! "; } } else { value = glp_mip_col_val(lp,col_num); } out << value << ";"; //допишем коэффициенты ещё //out << "*(" << glp_get_obj_coef(lp,col_num) << ");"; j++; col_num=glp_find_col(lp,GenerateColName(buff, name, i, j)); if (!col_num) { out << endl; i++; j=1; col_num=glp_find_col(lp,GenerateColName(buff, name, i, j)); } } }
vector<int> LinearProblem::ElasticFilter() const { LinearProblem tmp(*this); int realCols = glp_get_num_cols(tmp.lp_); for (int i = realCols; i > 0; --i) { // set old coefs to zero glp_set_obj_coef(tmp.lp_, i, 0); } int elasticCols = glp_get_num_rows(tmp.lp_); glp_add_cols(tmp.lp_, elasticCols); for (int i = 1; i <= elasticCols; ++i) { int indices[MAX_VARS]; double values[MAX_VARS]; int nonZeros = glp_get_mat_row(tmp.lp_, i, indices, values); indices[nonZeros + 1] = realCols + i; values[nonZeros + 1] = 1.0; glp_set_mat_row(tmp.lp_, i, nonZeros + 1, indices, values); glp_set_obj_coef(tmp.lp_, realCols + i, 1); glp_set_col_bnds(tmp.lp_, realCols + i, GLP_UP, 0.0, 0.0); } vector<int> suspects; glp_std_basis(tmp.lp_); int status = tmp.Solve(); while ((status != GLP_INFEAS) && (status != GLP_NOFEAS)) { for (int i = 1; i <= elasticCols; ++i) { if (glp_get_col_prim(tmp.lp_, realCols + i) < 0) { suspects.push_back(i); glp_set_col_bnds(tmp.lp_, realCols + i, GLP_FX, 0.0, 0.0); } } status = tmp.Solve(); } return suspects; }
inline void GetSolArray(glp_prob* lp, char* name, vector<vector<double>> &arr, bool integer=false) { arr.clear(); char buff[256]; int i=1; int j=1; double value; glp_create_index(lp); int col_num=glp_find_col(lp,GenerateColName(buff, name, i, j)); vector<double> row; while( col_num ) { if (!integer) { value = glp_get_col_prim(lp,col_num); } else { value = glp_mip_col_val(lp,col_num); } row.push_back(value); //cout << value << ";"; j++; col_num=glp_find_col(lp,GenerateColName(buff, name, i, j)); if (!col_num) { arr.push_back(row); //cout << endl; row.clear(); i++; j=1; col_num=glp_find_col(lp,GenerateColName(buff, name, i, j)); } } }
int glp_mpl_postsolve(glp_tran *tran, glp_prob *prob, int sol) { /* postsolve the model */ int j, m, n, ret; double x; if (!(tran->phase == 3 && !tran->flag_p)) xerror("glp_mpl_postsolve: invalid call sequence\n"); if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP)) xerror("glp_mpl_postsolve: sol = %d; invalid parameter\n", sol); m = mpl_get_num_rows(tran); n = mpl_get_num_cols(tran); if (!(m == glp_get_num_rows(prob) && n == glp_get_num_cols(prob))) xerror("glp_mpl_postsolve: wrong problem object\n"); if (!mpl_has_solve_stmt(tran)) { ret = 0; goto done; } for (j = 1; j <= n; j++) { if (sol == GLP_SOL) x = glp_get_col_prim(prob, j); else if (sol == GLP_IPT) x = glp_ipt_col_prim(prob, j); else if (sol == GLP_MIP) x = glp_mip_col_val(prob, j); else xassert(sol != sol); if (fabs(x) < 1e-9) x = 0.0; mpl_put_col_value(tran, j, x); } ret = mpl_postsolve(tran); if (ret == 3) ret = 0; else if (ret == 4) ret = 1; done: return ret; }
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; }
double lpx_get_col_prim(LPX *lp, int j) { /* retrieve column primal value (basic solution) */ return glp_get_col_prim(lp, j); }
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 glp_mpl_postsolve(glp_tran *tran, glp_prob *prob, int sol) { /* postsolve the model */ int i, j, m, n, stat, ret; double prim, dual; if (!(tran->phase == 3 && !tran->flag_p)) xerror("glp_mpl_postsolve: invalid call sequence\n"); if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP)) xerror("glp_mpl_postsolve: sol = %d; invalid parameter\n", sol); m = mpl_get_num_rows(tran); n = mpl_get_num_cols(tran); if (!(m == glp_get_num_rows(prob) && n == glp_get_num_cols(prob))) xerror("glp_mpl_postsolve: wrong problem object\n"); if (!mpl_has_solve_stmt(tran)) { ret = 0; goto done; } for (i = 1; i <= m; i++) { if (sol == GLP_SOL) { stat = glp_get_row_stat(prob, i); prim = glp_get_row_prim(prob, i); dual = glp_get_row_dual(prob, i); } else if (sol == GLP_IPT) { stat = 0; prim = glp_ipt_row_prim(prob, i); dual = glp_ipt_row_dual(prob, i); } else if (sol == GLP_MIP) { stat = 0; prim = glp_mip_row_val(prob, i); dual = 0.0; } else xassert(sol != sol); if (fabs(prim) < 1e-9) prim = 0.0; if (fabs(dual) < 1e-9) dual = 0.0; mpl_put_row_soln(tran, i, stat, prim, dual); } for (j = 1; j <= n; j++) { if (sol == GLP_SOL) { stat = glp_get_col_stat(prob, j); prim = glp_get_col_prim(prob, j); dual = glp_get_col_dual(prob, j); } else if (sol == GLP_IPT) { stat = 0; prim = glp_ipt_col_prim(prob, j); dual = glp_ipt_col_dual(prob, j); } else if (sol == GLP_MIP) { stat = 0; prim = glp_mip_col_val(prob, j); dual = 0.0; } else xassert(sol != sol); if (fabs(prim) < 1e-9) prim = 0.0; if (fabs(dual) < 1e-9) dual = 0.0; mpl_put_col_soln(tran, j, stat, prim, dual); } ret = mpl_postsolve(tran); if (ret == 3) ret = 0; else if (ret == 4) ret = 1; done: return ret; }
static bool Graph_solve(Graph& graph, size_t loops, PositionList* position_tbl) { glp_prob* lp = glp_create_prob(); glp_set_prob_name(lp, "scaffold"); glp_set_obj_dir(lp, GLP_MIN); size_t rows = 0, cols = 0, vals = 0; for (Graph::const_iterator i = graph.begin(); i != graph.end(); ++i) { ++cols; // var x_i for (Children::const_iterator j = i->second.children.begin(); j != i->second.children.end(); ++j) { rows += 3; cols += 2; // var e_i_j; var E_i_j; vals += 7; } } glp_add_rows(lp, rows); glp_add_cols(lp, cols); std::map< std::pair< size_t, size_t >, size_t > mapping; { size_t row = 1, col = 1; for (Graph::const_iterator i = graph.begin(); i != graph.end(); ++i) { mapping[std::make_pair(i->first, -1)] = col; glp_set_col_bnds(lp, col++, GLP_LO, 0.0, 0.0); // x_i >= 0 for (Children::const_iterator j = i->second.children.begin(); j != i->second.children.end(); ++j) { glp_set_row_bnds(lp, row++, GLP_FX, j->second, j->second); glp_set_row_bnds(lp, row++, GLP_LO, 0.0, 0.0); glp_set_row_bnds(lp, row++, GLP_LO, 0.0, 0.0); mapping[std::make_pair(i->first, j->first)] = col; ++col; // var e_i glp_set_obj_coef(lp, col++, 1.0); } } } LOG4CXX_TRACE(logger, boost::format(" rows = %d, cols = %d, vals = %d") % rows % cols % vals); int* ia = new int[vals + 1]; int* ja = new int[vals + 1]; double* ra = new double[vals + 1]; { size_t l = 1, row = 1, col = 1; for (Graph::const_iterator i = graph.begin(); i != graph.end(); ++i) { for (Children::const_iterator j = i->second.children.begin(); j != i->second.children.end(); ++j) { // x_j - x_i + e_i_j = d_i_j ia[l] = row; ja[l] = mapping[std::make_pair(j->first, -1)]; ra[l] = 1.0; ++l; ia[l] = row; ja[l] = mapping[std::make_pair(i->first, -1)]; ra[l] = -1.0; ++l; ia[l] = row; ja[l] = mapping[std::make_pair(i->first, j->first)] + 0; ra[l] = 1.0; ++l; ++row; // E_i_j + e_i_j >= 0 ia[l] = row; ja[l] = mapping[std::make_pair(i->first, j->first)] + 1; ra[l] = 1.0; ++l; ia[l] = row; ja[l] = mapping[std::make_pair(i->first, j->first)] + 0; ra[l] = 1.0; ++l; ++row; // E_i_j - e_i_j >= 0 ia[l] = row; ja[l] = mapping[std::make_pair(i->first, j->first)] + 1; ra[l] = 1.0; ++l; ia[l] = row; ja[l] = mapping[std::make_pair(i->first, j->first)] + 0; ra[l] = -1.0; ++l; ++row; } } } glp_load_matrix(lp, vals, ia, ja, ra); glp_smcp parm; glp_init_smcp(&parm); parm.it_lim = loops; //parm.pricing = GLP_PT_PSE; //parm.presolve = GLP_ON; parm.msg_lev = GLP_MSG_ERR; glp_simplex(lp, &parm); double z = glp_get_obj_val(lp); LOG4CXX_TRACE(logger, boost::format("z = %f") % z); for (Graph::const_iterator i = graph.begin(); i != graph.end(); ++i) { size_t val = glp_get_col_prim(lp, mapping[std::make_pair(i->first, -1)]); if (position_tbl != NULL) { (*position_tbl)[i->first] = val; } LOG4CXX_TRACE(logger, boost::format("x\t%d\t%d") % i->first % val); } delete[] ra; delete[] ja; delete[] ia; glp_delete_prob(lp); return true; }
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 CConstraints::GLPK_lp(CModel* pmodel) { glp_prob* lp = glp_create_prob(); int iRow = (int) m_vWeights.size(); //int iCol = (int) m_iWeightLength + m_iPatternNum; int iSize = iRow * ( m_iWeightLength + 1); int ia[10 + iSize], ja[1 + iSize]; double ar[1 + iSize]; glp_set_prob_name(lp, "StrLP"); glp_set_obj_dir(lp, GLP_MIN); glp_add_rows(lp, (int) m_vWeights.size()); // setup rows for (int i = 0; i < (int) m_vWeights.size(); i ++) { char tmp[200]; sprintf(tmp, "cc_%d", i + 1); glp_set_row_name(lp, i + 1, tmp); glp_set_row_bnds(lp, i + 1, GLP_LO, m_fDistance - m_fEpsilon, 0); } glp_add_cols(lp, m_iWeightLength + m_iPatternNum); for (int i = 0; i < m_iWeightLength; i ++) { char tmp[200]; sprintf(tmp, "w%d", i + 1); glp_set_col_name(lp, i + 1, tmp); glp_set_col_bnds(lp, i + 1, GLP_LO, 0, 0.0); glp_set_obj_coef(lp, i + 1, 1.0); } for (int i = 0; i < m_iPatternNum; i ++) { char tmp[200]; sprintf(tmp, "e%d", i + 1); glp_set_col_name(lp, m_iWeightLength + i + 1, tmp); glp_set_col_bnds(lp, m_iWeightLength + i + 1, GLP_LO, 0, 0.0); glp_set_obj_coef(lp, m_iWeightLength + i + 1, m_fC / m_iPatternNum); } int iIndex = 1; for (int i = 0; i < (int)m_vWeights.size(); i ++) { double* pd = m_vWeights[i]; for (int j = 0; j < (int) m_iWeightLength; j ++) { ia[iIndex] = i + 1, ja[iIndex] = j + 1; if (pmodel->m_vSign[j] <= 0) { ar[iIndex] = -pd[j]; } else { ar[iIndex] = pd[j]; } iIndex ++; } ia[iIndex] = i + 1; ja[iIndex] = m_iWeightLength + m_vPatternIndex[i] + 1; //ar[iIndex] = 1; ar[iIndex] = m_vLoss[i]; iIndex ++; } glp_load_matrix(lp, iIndex - 1, ia, ja, ar); glp_simplex(lp, NULL); double z = glp_get_obj_val(lp); fprintf(stderr, "minimal value %f \n", z); for (int i = 0; i < m_iWeightLength; i ++) { double x = glp_get_col_prim(lp, i + 1); if (pmodel->m_vSign[i] <=0) { pmodel->m_vWeight[i] = -x; } else { pmodel->m_vWeight[i] = x; } if (x != 0) fprintf(stderr, "(w%d, %f)\t", i + 1, pmodel->m_vWeight[i]); } for (int i = 0; i < m_iPatternNum; i ++) { double x = glp_get_col_prim(lp, m_iWeightLength + i + 1); pmodel->m_vTheta[i] = x; if (x != 0) fprintf(stderr, "(e%d, %f)\t", i + 1, pmodel->m_vTheta[i]); } glp_delete_prob(lp); return 1; }
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; }
double c_glp_get_col_prim(glp_prob *lp, int i){ return glp_get_col_prim(lp, i); }
static PyObject *simplex(PyObject *self, PyObject *args, PyObject *kwrds) { matrix *c, *h, *b=NULL, *x=NULL, *z=NULL, *y=NULL; PyObject *G, *A=NULL, *t=NULL; glp_prob *lp; glp_smcp *options = NULL; pysmcp *smcpParm = NULL; int m, n, p, i, j, k, nnz, nnzmax, *rn=NULL, *cn=NULL; double *a=NULL, val; char *kwlist[] = {"c", "G", "h", "A", "b","options", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|OOO!", kwlist, &c, &G, &h, &A, &b,&smcp_t,&smcpParm)) return NULL; if ((Matrix_Check(G) && MAT_ID(G) != DOUBLE) || (SpMatrix_Check(G) && SP_ID(G) != DOUBLE) || (!Matrix_Check(G) && !SpMatrix_Check(G))){ PyErr_SetString(PyExc_TypeError, "G must be a 'd' matrix"); return NULL; } if ((m = Matrix_Check(G) ? MAT_NROWS(G) : SP_NROWS(G)) <= 0) err_p_int("m"); if ((n = Matrix_Check(G) ? MAT_NCOLS(G) : SP_NCOLS(G)) <= 0) err_p_int("n"); if (!Matrix_Check(h) || h->id != DOUBLE) err_dbl_mtrx("h"); if (h->nrows != m || h->ncols != 1){ PyErr_SetString(PyExc_ValueError, "incompatible dimensions"); return NULL; } if (A){ if ((Matrix_Check(A) && MAT_ID(A) != DOUBLE) || (SpMatrix_Check(A) && SP_ID(A) != DOUBLE) || (!Matrix_Check(A) && !SpMatrix_Check(A))){ PyErr_SetString(PyExc_ValueError, "A must be a dense " "'d' matrix or a general sparse matrix"); return NULL; } if ((p = Matrix_Check(A) ? MAT_NROWS(A) : SP_NROWS(A)) < 0) err_p_int("p"); if ((Matrix_Check(A) ? MAT_NCOLS(A) : SP_NCOLS(A)) != n){ PyErr_SetString(PyExc_ValueError, "incompatible " "dimensions"); return NULL; } } else p = 0; if (b && (!Matrix_Check(b) || b->id != DOUBLE)) err_dbl_mtrx("b"); if ((b && (b->nrows != p || b->ncols != 1)) || (!b && p !=0 )){ PyErr_SetString(PyExc_ValueError, "incompatible dimensions"); return NULL; } if(!smcpParm) { smcpParm = (pysmcp*)malloc(sizeof(*smcpParm)); glp_init_smcp(&(smcpParm->obj)); } if(smcpParm) { Py_INCREF(smcpParm); options = &smcpParm->obj; options->presolve = 1; } lp = glp_create_prob(); glp_add_rows(lp, m+p); glp_add_cols(lp, n); for (i=0; i<n; i++){ glp_set_obj_coef(lp, i+1, MAT_BUFD(c)[i]); glp_set_col_bnds(lp, i+1, GLP_FR, 0.0, 0.0); } for (i=0; i<m; i++) glp_set_row_bnds(lp, i+1, GLP_UP, 0.0, MAT_BUFD(h)[i]); for (i=0; i<p; i++) glp_set_row_bnds(lp, i+m+1, GLP_FX, MAT_BUFD(b)[i], MAT_BUFD(b)[i]); nnzmax = (SpMatrix_Check(G) ? SP_NNZ(G) : m*n ) + ((A && SpMatrix_Check(A)) ? SP_NNZ(A) : p*n); a = (double *) calloc(nnzmax+1, sizeof(double)); rn = (int *) calloc(nnzmax+1, sizeof(int)); cn = (int *) calloc(nnzmax+1, sizeof(int)); if (!a || !rn || !cn){ free(a); free(rn); free(cn); glp_delete_prob(lp); return PyErr_NoMemory(); } nnz = 0; if (SpMatrix_Check(G)) { for (j=0; j<n; j++) for (k=SP_COL(G)[j]; k<SP_COL(G)[j+1]; k++) if ((val = SP_VALD(G)[k]) != 0.0){ a[1+nnz] = val; rn[1+nnz] = SP_ROW(G)[k]+1; cn[1+nnz] = j+1; nnz++; } } else for (j=0; j<n; j++) for (i=0; i<m; i++) if ((val = MAT_BUFD(G)[i+j*m]) != 0.0){ a[1+nnz] = val; rn[1+nnz] = i+1; cn[1+nnz] = j+1; nnz++; } if (A && SpMatrix_Check(A)){ for (j=0; j<n; j++) for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1]; k++) if ((val = SP_VALD(A)[k]) != 0.0){ a[1+nnz] = val; rn[1+nnz] = m+SP_ROW(A)[k]+1; cn[1+nnz] = j+1; nnz++; } } else for (j=0; j<n; j++) for (i=0; i<p; i++) if ((val = MAT_BUFD(A)[i+j*p]) != 0.0){ a[1+nnz] = val; rn[1+nnz] = m+i+1; cn[1+nnz] = j+1; nnz++; } glp_load_matrix(lp, nnz, rn, cn, a); free(rn); free(cn); free(a); if (!(t = PyTuple_New(A ? 4 : 3))){ glp_delete_prob(lp); return PyErr_NoMemory(); } switch (glp_simplex(lp,options)){ case 0: x = (matrix *) Matrix_New(n,1,DOUBLE); z = (matrix *) Matrix_New(m,1,DOUBLE); if (A) y = (matrix *) Matrix_New(p,1,DOUBLE); if (!x || !z || (A && !y)){ Py_XDECREF(x); Py_XDECREF(z); Py_XDECREF(y); Py_XDECREF(t); Py_XDECREF(smcpParm); glp_delete_prob(lp); return PyErr_NoMemory(); } set_output_string(t,"optimal"); for (i=0; i<n; i++) MAT_BUFD(x)[i] = glp_get_col_prim(lp, i+1); PyTuple_SET_ITEM(t, 1, (PyObject *) x); for (i=0; i<m; i++) MAT_BUFD(z)[i] = -glp_get_row_dual(lp, i+1); PyTuple_SET_ITEM(t, 2, (PyObject *) z); if (A){ for (i=0; i<p; i++) MAT_BUFD(y)[i] = -glp_get_row_dual(lp, m+i+1); PyTuple_SET_ITEM(t, 3, (PyObject *) y); } Py_XDECREF(smcpParm); glp_delete_prob(lp); return (PyObject *) t; case GLP_EBADB: set_output_string(t,"incorrect initial basis"); break; case GLP_ESING: set_output_string(t,"singular initial basis matrix"); break; case GLP_ECOND: set_output_string(t,"ill-conditioned initial basis matrix"); break; case GLP_EBOUND: set_output_string(t,"incorrect bounds"); break; case GLP_EFAIL: set_output_string(t,"solver failure"); break; case GLP_EOBJLL: set_output_string(t,"objective function reached lower limit"); break; case GLP_EOBJUL: set_output_string(t,"objective function reached upper limit"); break; case GLP_EITLIM: set_output_string(t,"iteration limit exceeded"); break; case GLP_ETMLIM: set_output_string(t,"time limit exceeded"); break; case GLP_ENOPFS: set_output_string(t,"primal infeasible"); break; case GLP_ENODFS: set_output_string(t,"dual infeasible"); break; default: set_output_string(t,"unknown"); break; } Py_XDECREF(smcpParm); glp_delete_prob(lp); PyTuple_SET_ITEM(t, 1, Py_BuildValue("")); PyTuple_SET_ITEM(t, 2, Py_BuildValue("")); if (A) PyTuple_SET_ITEM(t, 3, Py_BuildValue("")); return (PyObject *) t; }
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; }
/* R is the random contraint data in row major memory layout ridx is an N array of integers soln is an array of length (n+1) soln[n] is t (objective value) active_constr is an N-length 0-1 array */ void solve_lp(int N, int n, double* R, int* ridx, double* soln, int* active_constr) { double tol = 1.0e-14; int size = (N+1)*(n+1) + 1; // We add one because GLPK indexes arrays // starting at 1 instead of 0. glp_prob *lp; int* ia = malloc(size * sizeof(int)); int* ja = malloc(size * sizeof(int)); double* ar = malloc(size * sizeof(double)); int i, j; lp = glp_create_prob(); glp_set_prob_name(lp, "portfolio"); glp_set_obj_dir(lp, GLP_MAX); glp_add_rows(lp, N+1); // Sampled constraints are ">= 0" for (i = 1; i <= N; i++) { glp_set_row_bnds(lp, i, GLP_LO, 0.0, 0.0); } // Sum = 1 constraint glp_set_row_name(lp, N+1, "sum"); glp_set_row_bnds(lp, N+1, GLP_FX, 1.0, 1.0); glp_add_cols(lp, n+1); // Nonnegative variables y for (i = 1; i <= n; i++) { glp_set_col_bnds(lp, i, GLP_LO, 0.0, 0.0); glp_set_obj_coef(lp, i, 0.0); } // Free variable t glp_set_col_name(lp, n+1, "t"); glp_set_col_bnds(lp, n+1, GLP_FR, 0.0, 0.0); glp_set_obj_coef(lp, n+1, 1.0); // for (i = 0; i < N*(n-1); i++) { // printf("%d: %g\n", i, R[i]); // } int idx = 1; // Sampled constraints for (i = 1; i <= N; i++) { // Uncertain assets for (j = 1; j < n; j++) { ia[idx] = i; ja[idx] = j; ar[idx] = R[ ridx[(i-1)] * (n-1) + (j-1) ]; idx += 1; } // Fixed return asset ia[idx] = i; ja[idx] = n; ar[idx] = 1.05; idx += 1; // t ia[idx] = i; ja[idx] = n+1; ar[idx] = -1.0; idx += 1; } // Sum = 1 constraint for (i = 1; i <= n; i++) { ia[idx] = N+1; ja[idx] = i; ar[idx] = 1.0; idx += 1; } // t ia[idx] = N+1; ja[idx] = n+1; ar[idx] = 0.0; idx += 1; // for (i = 1; i < size; i++) { // printf("%d %d %g\n", ia[i], ja[i], ar[i]); // } glp_load_matrix(lp, size-1, ia, ja, ar); // glp_scale_prob(lp, GLP_SF_AUTO); glp_smcp param; glp_init_smcp(¶m); param.meth = GLP_PRIMAL; //glp_std_basis(lp); glp_simplex(lp, ¶m); double z = glp_get_obj_val(lp); // printf("z = %g\n", z); if (soln) { for (i = 0; i < n; i++) { double y = glp_get_col_prim(lp, i+1); soln[i] = y; // printf("y%d = %g\n", i, y); } double t = glp_get_col_prim(lp, n+1); soln[n] = t; // printf("t = %g\n", glp_get_col_prim(lp, n+1)); } for (i = 1; i <= N; i++) { double slack = glp_get_row_prim(lp, i); active_constr[i-1] = fabs(slack) < tol ? 1 : 0; // printf("constr%d %d\n", i, active_constr[i-1]); } glp_delete_prob(lp); // glp_free_env(); free(ia); free(ja); free(ar); }
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; }
double NUMlinprog_getPrimalValue (NUMlinprog me, long ivar) { return glp_get_col_prim (my linearProgram, ivar); }