int main(void) { LPX *lp; int ia[1+1000], ja[1+1000]; double ar[1+1000], Z, x1, x2, x3; s1: lp = lpx_create_prob(); s2: lpx_set_prob_name(lp, "sample"); s3: lpx_set_obj_dir(lp, LPX_MAX); s4: lpx_add_rows(lp, 3); s5: lpx_set_row_name(lp, 1, "p"); s6: lpx_set_row_bnds(lp, 1, LPX_UP, 0.0, 100.0); s7: lpx_set_row_name(lp, 2, "q"); s8: lpx_set_row_bnds(lp, 2, LPX_UP, 0.0, 600.0); s9: lpx_set_row_name(lp, 3, "r"); s10: lpx_set_row_bnds(lp, 3, LPX_UP, 0.0, 300.0); s11: lpx_add_cols(lp, 3); s12: lpx_set_col_name(lp, 1, "x1"); s13: lpx_set_col_bnds(lp, 1, LPX_LO, 0.0, 0.0); s14: lpx_set_obj_coef(lp, 1, 10.0); s15: lpx_set_col_name(lp, 2, "x2"); s16: lpx_set_col_bnds(lp, 2, LPX_LO, 0.0, 0.0); s17: lpx_set_obj_coef(lp, 2, 6.0); s18: lpx_set_col_name(lp, 3, "x3"); s19: lpx_set_col_bnds(lp, 3, LPX_LO, 0.0, 0.0); s20: lpx_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: lpx_load_matrix(lp, 9, ia, ja, ar); s31: lpx_simplex(lp); s32: Z = lpx_get_obj_val(lp); s33: x1 = lpx_get_col_prim(lp, 1); s34: x2 = lpx_get_col_prim(lp, 2); s35: x3 = lpx_get_col_prim(lp, 3); s36: printf("\nZ = %g; x1 = %g; x2 = %g; x3 = %g\n", Z, x1, x2, x3); s37: lpx_delete_prob(lp); return 0; }
static void show_status(LPX *prob, int prob_m, int prob_nz) { int n, j, count; double x, tol_int; /* determine the number of structural variables of integer kind whose current values are still fractional */ n = lpx_get_num_cols(prob); tol_int = lpx_get_real_parm(prob, LPX_K_TOLINT); count = 0; for (j = 1; j <= n; j++) { if (lpx_get_col_kind(prob, j) != LPX_IV) continue; x = lpx_get_col_prim(prob, j); if (fabs(x - floor(x + 0.5)) <= tol_int) continue; count++; } print("&%6d: obj = %17.9e frac = %5d cuts = %5d (%d)", lpx_get_int_parm(prob, LPX_K_ITCNT), lpx_get_obj_val(prob), count, lpx_get_num_rows(prob) - prob_m, lpx_get_num_nz(prob) - prob_nz); return; }
int lpx_print_prob(LPX *lp, const char *fname) { XFILE *fp; int m, n, mip, i, j, len, t, type, *ndx; double coef, lb, ub, *val; char *str, name[255+1]; xprintf("lpx_write_prob: writing problem data to `%s'...\n", fname); fp = xfopen(fname, "w"); if (fp == NULL) { xprintf("lpx_write_prob: unable to create `%s' - %s\n", fname, strerror(errno)); goto fail; } m = lpx_get_num_rows(lp); n = lpx_get_num_cols(lp); mip = (lpx_get_class(lp) == LPX_MIP); str = (void *)lpx_get_prob_name(lp); xfprintf(fp, "Problem: %s\n", str == NULL ? "(unnamed)" : str); xfprintf(fp, "Class: %s\n", !mip ? "LP" : "MIP"); xfprintf(fp, "Rows: %d\n", m); if (!mip) xfprintf(fp, "Columns: %d\n", n); else xfprintf(fp, "Columns: %d (%d integer, %d binary)\n", n, lpx_get_num_int(lp), lpx_get_num_bin(lp)); xfprintf(fp, "Non-zeros: %d\n", lpx_get_num_nz(lp)); xfprintf(fp, "\n"); xfprintf(fp, "*** OBJECTIVE FUNCTION ***\n"); xfprintf(fp, "\n"); switch (lpx_get_obj_dir(lp)) { case LPX_MIN: xfprintf(fp, "Minimize:"); break; case LPX_MAX: xfprintf(fp, "Maximize:"); break; default: xassert(lp != lp); } str = (void *)lpx_get_obj_name(lp); xfprintf(fp, " %s\n", str == NULL ? "(unnamed)" : str); coef = lpx_get_obj_coef(lp, 0); if (coef != 0.0) xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, coef, "(constant term)"); for (i = 1; i <= m; i++) #if 0 { coef = lpx_get_row_coef(lp, i); #else { coef = 0.0; #endif if (coef != 0.0) xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, coef, row_name(lp, i, name)); } for (j = 1; j <= n; j++) { coef = lpx_get_obj_coef(lp, j); if (coef != 0.0) xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, coef, col_name(lp, j, name)); } xfprintf(fp, "\n"); xfprintf(fp, "*** ROWS (CONSTRAINTS) ***\n"); ndx = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); for (i = 1; i <= m; i++) { xfprintf(fp, "\n"); xfprintf(fp, "Row %d: %s", i, row_name(lp, i, name)); lpx_get_row_bnds(lp, i, &type, &lb, &ub); switch (type) { case LPX_FR: xfprintf(fp, " free"); break; case LPX_LO: xfprintf(fp, " >= %.*g", DBL_DIG, lb); break; case LPX_UP: xfprintf(fp, " <= %.*g", DBL_DIG, ub); break; case LPX_DB: xfprintf(fp, " >= %.*g <= %.*g", DBL_DIG, lb, DBL_DIG, ub); break; case LPX_FX: xfprintf(fp, " = %.*g", DBL_DIG, lb); break; default: xassert(type != type); } xfprintf(fp, "\n"); #if 0 coef = lpx_get_row_coef(lp, i); #else coef = 0.0; #endif if (coef != 0.0) xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, coef, "(objective)"); len = lpx_get_mat_row(lp, i, ndx, val); for (t = 1; t <= len; t++) xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, val[t], col_name(lp, ndx[t], name)); } xfree(ndx); xfree(val); xfprintf(fp, "\n"); xfprintf(fp, "*** COLUMNS (VARIABLES) ***\n"); ndx = xcalloc(1+m, sizeof(int)); val = xcalloc(1+m, sizeof(double)); for (j = 1; j <= n; j++) { xfprintf(fp, "\n"); xfprintf(fp, "Col %d: %s", j, col_name(lp, j, name)); if (mip) { switch (lpx_get_col_kind(lp, j)) { case LPX_CV: break; case LPX_IV: xfprintf(fp, " integer"); break; default: xassert(lp != lp); } } lpx_get_col_bnds(lp, j, &type, &lb, &ub); switch (type) { case LPX_FR: xfprintf(fp, " free"); break; case LPX_LO: xfprintf(fp, " >= %.*g", DBL_DIG, lb); break; case LPX_UP: xfprintf(fp, " <= %.*g", DBL_DIG, ub); break; case LPX_DB: xfprintf(fp, " >= %.*g <= %.*g", DBL_DIG, lb, DBL_DIG, ub); break; case LPX_FX: xfprintf(fp, " = %.*g", DBL_DIG, lb); break; default: xassert(type != type); } xfprintf(fp, "\n"); coef = lpx_get_obj_coef(lp, j); if (coef != 0.0) xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, coef, "(objective)"); len = lpx_get_mat_col(lp, j, ndx, val); for (t = 1; t <= len; t++) xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, val[t], row_name(lp, ndx[t], name)); } xfree(ndx); xfree(val); xfprintf(fp, "\n"); xfprintf(fp, "End of output\n"); xfflush(fp); if (xferror(fp)) { xprintf("lpx_write_prob: write error on `%s' - %s\n", fname, strerror(errno)); goto fail; } xfclose(fp); return 0; fail: if (fp != NULL) xfclose(fp); return 1; } #undef row_name #undef col_name /*---------------------------------------------------------------------- -- lpx_print_sol - write LP problem solution in printable format. -- -- *Synopsis* -- -- #include "glplpx.h" -- int lpx_print_sol(LPX *lp, char *fname); -- -- *Description* -- -- The routine lpx_print_sol writes the current basic solution of an LP -- problem, which is specified by the pointer lp, to a text file, whose -- name is the character string fname, in printable format. -- -- Information reported by the routine lpx_print_sol is intended mainly -- for visual analysis. -- -- *Returns* -- -- If the operation was successful, the routine returns zero. Otherwise -- the routine prints an error message and returns non-zero. */ int lpx_print_sol(LPX *lp, const char *fname) { XFILE *fp; int what, round; xprintf( "lpx_print_sol: writing LP problem solution to `%s'...\n", fname); fp = xfopen(fname, "w"); if (fp == NULL) { xprintf("lpx_print_sol: can't create `%s' - %s\n", fname, strerror(errno)); goto fail; } /* problem name */ { const char *name; name = lpx_get_prob_name(lp); if (name == NULL) name = ""; xfprintf(fp, "%-12s%s\n", "Problem:", name); } /* number of rows (auxiliary variables) */ { int nr; nr = lpx_get_num_rows(lp); xfprintf(fp, "%-12s%d\n", "Rows:", nr); } /* number of columns (structural variables) */ { int nc; nc = lpx_get_num_cols(lp); xfprintf(fp, "%-12s%d\n", "Columns:", nc); } /* number of non-zeros (constraint coefficients) */ { int nz; nz = lpx_get_num_nz(lp); xfprintf(fp, "%-12s%d\n", "Non-zeros:", nz); } /* solution status */ { int status; status = lpx_get_status(lp); xfprintf(fp, "%-12s%s\n", "Status:", status == LPX_OPT ? "OPTIMAL" : status == LPX_FEAS ? "FEASIBLE" : status == LPX_INFEAS ? "INFEASIBLE (INTERMEDIATE)" : status == LPX_NOFEAS ? "INFEASIBLE (FINAL)" : status == LPX_UNBND ? "UNBOUNDED" : status == LPX_UNDEF ? "UNDEFINED" : "???"); } /* objective function */ { char *name; int dir; double obj; name = (void *)lpx_get_obj_name(lp); dir = lpx_get_obj_dir(lp); obj = lpx_get_obj_val(lp); xfprintf(fp, "%-12s%s%s%.10g %s\n", "Objective:", name == NULL ? "" : name, name == NULL ? "" : " = ", obj, dir == LPX_MIN ? "(MINimum)" : dir == LPX_MAX ? "(MAXimum)" : "(" "???" ")"); } /* main sheet */ for (what = 1; what <= 2; what++) { int mn, ij; xfprintf(fp, "\n"); xfprintf(fp, " No. %-12s St Activity Lower bound Upp" "er bound Marginal\n", what == 1 ? " Row name" : "Column name"); xfprintf(fp, "------ ------------ -- ------------- -----------" "-- ------------- -------------\n"); mn = (what == 1 ? lpx_get_num_rows(lp) : lpx_get_num_cols(lp)); for (ij = 1; ij <= mn; ij++) { const char *name; int typx, tagx; double lb, ub, vx, dx; if (what == 1) { name = lpx_get_row_name(lp, ij); if (name == NULL) name = ""; lpx_get_row_bnds(lp, ij, &typx, &lb, &ub); round = lpx_get_int_parm(lp, LPX_K_ROUND); lpx_set_int_parm(lp, LPX_K_ROUND, 1); lpx_get_row_info(lp, ij, &tagx, &vx, &dx); lpx_set_int_parm(lp, LPX_K_ROUND, round); } else { name = lpx_get_col_name(lp, ij); if (name == NULL) name = ""; lpx_get_col_bnds(lp, ij, &typx, &lb, &ub); round = lpx_get_int_parm(lp, LPX_K_ROUND); lpx_set_int_parm(lp, LPX_K_ROUND, 1); lpx_get_col_info(lp, ij, &tagx, &vx, &dx); lpx_set_int_parm(lp, LPX_K_ROUND, round); } /* row/column ordinal number */ xfprintf(fp, "%6d ", ij); /* row column/name */ if (strlen(name) <= 12) xfprintf(fp, "%-12s ", name); else xfprintf(fp, "%s\n%20s", name, ""); /* row/column status */ xfprintf(fp, "%s ", tagx == LPX_BS ? "B " : tagx == LPX_NL ? "NL" : tagx == LPX_NU ? "NU" : tagx == LPX_NF ? "NF" : tagx == LPX_NS ? "NS" : "??"); /* row/column primal activity */ xfprintf(fp, "%13.6g ", vx); /* row/column lower bound */ if (typx == LPX_LO || typx == LPX_DB || typx == LPX_FX) xfprintf(fp, "%13.6g ", lb); else xfprintf(fp, "%13s ", ""); /* row/column upper bound */ if (typx == LPX_UP || typx == LPX_DB) xfprintf(fp, "%13.6g ", ub); else if (typx == LPX_FX) xfprintf(fp, "%13s ", "="); else xfprintf(fp, "%13s ", ""); /* row/column dual activity */ if (tagx != LPX_BS) { if (dx == 0.0) xfprintf(fp, "%13s", "< eps"); else xfprintf(fp, "%13.6g", dx); } /* end of line */ xfprintf(fp, "\n"); } } xfprintf(fp, "\n"); #if 1 if (lpx_get_prim_stat(lp) != LPX_P_UNDEF && lpx_get_dual_stat(lp) != LPX_D_UNDEF) { int m = lpx_get_num_rows(lp); LPXKKT kkt; xfprintf(fp, "Karush-Kuhn-Tucker optimality conditions:\n\n"); lpx_check_kkt(lp, 1, &kkt); xfprintf(fp, "KKT.PE: max.abs.err. = %.2e on row %d\n", kkt.pe_ae_max, kkt.pe_ae_row); xfprintf(fp, " max.rel.err. = %.2e on row %d\n", kkt.pe_re_max, kkt.pe_re_row); switch (kkt.pe_quality) { case 'H': xfprintf(fp, " High quality\n"); break; case 'M': xfprintf(fp, " Medium quality\n"); break; case 'L': xfprintf(fp, " Low quality\n"); break; default: xfprintf(fp, " PRIMAL SOLUTION IS WRONG\n"); break; } xfprintf(fp, "\n"); xfprintf(fp, "KKT.PB: max.abs.err. = %.2e on %s %d\n", kkt.pb_ae_max, kkt.pb_ae_ind <= m ? "row" : "column", kkt.pb_ae_ind <= m ? kkt.pb_ae_ind : kkt.pb_ae_ind - m); xfprintf(fp, " max.rel.err. = %.2e on %s %d\n", kkt.pb_re_max, kkt.pb_re_ind <= m ? "row" : "column", kkt.pb_re_ind <= m ? kkt.pb_re_ind : kkt.pb_re_ind - m); switch (kkt.pb_quality) { case 'H': xfprintf(fp, " High quality\n"); break; case 'M': xfprintf(fp, " Medium quality\n"); break; case 'L': xfprintf(fp, " Low quality\n"); break; default: xfprintf(fp, " PRIMAL SOLUTION IS INFEASIBLE\n"); break; } xfprintf(fp, "\n"); xfprintf(fp, "KKT.DE: max.abs.err. = %.2e on column %d\n", kkt.de_ae_max, kkt.de_ae_col); xfprintf(fp, " max.rel.err. = %.2e on column %d\n", kkt.de_re_max, kkt.de_re_col); switch (kkt.de_quality) { case 'H': xfprintf(fp, " High quality\n"); break; case 'M': xfprintf(fp, " Medium quality\n"); break; case 'L': xfprintf(fp, " Low quality\n"); break; default: xfprintf(fp, " DUAL SOLUTION IS WRONG\n"); break; } xfprintf(fp, "\n"); xfprintf(fp, "KKT.DB: max.abs.err. = %.2e on %s %d\n", kkt.db_ae_max, kkt.db_ae_ind <= m ? "row" : "column", kkt.db_ae_ind <= m ? kkt.db_ae_ind : kkt.db_ae_ind - m); xfprintf(fp, " max.rel.err. = %.2e on %s %d\n", kkt.db_re_max, kkt.db_re_ind <= m ? "row" : "column", kkt.db_re_ind <= m ? kkt.db_re_ind : kkt.db_re_ind - m); switch (kkt.db_quality) { case 'H': xfprintf(fp, " High quality\n"); break; case 'M': xfprintf(fp, " Medium quality\n"); break; case 'L': xfprintf(fp, " Low quality\n"); break; default: xfprintf(fp, " DUAL SOLUTION IS INFEASIBLE\n"); break; } xfprintf(fp, "\n"); } #endif #if 1 if (lpx_get_status(lp) == LPX_UNBND) { int m = lpx_get_num_rows(lp); int k = lpx_get_ray_info(lp); xfprintf(fp, "Unbounded ray: %s %d\n", k <= m ? "row" : "column", k <= m ? k : k - m); xfprintf(fp, "\n"); } #endif xfprintf(fp, "End of output\n"); xfflush(fp); if (xferror(fp)) { xprintf("lpx_print_sol: can't write to `%s' - %s\n", fname, strerror(errno)); goto fail; } xfclose(fp); return 0; fail: if (fp != NULL) xfclose(fp); return 1; }
int CClp_objval(CClp *lp, double *obj) { /* RETURNS the objective value of the lp. */ if (obj != NULL) *obj = lpx_get_obj_val(lp->lp); return 0; }
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; }
OptSolutionData* GLPKRunSolver(int ProbType) { OptSolutionData* NewSolution = NULL; int NumVariables = lpx_get_num_cols(GLPKModel); int Status = 0; if (ProbType == MILP) { Status = lpx_simplex(GLPKModel); if (Status != LPX_E_OK) { FErrorFile() << "Failed to optimize problem." << endl; FlushErrorFile(); return NULL; } Status = lpx_integer(GLPKModel); if (Status != LPX_E_OK) { FErrorFile() << "Failed to optimize problem." << endl; FlushErrorFile(); return NULL; } NewSolution = new OptSolutionData; Status = lpx_mip_status(GLPKModel); if (Status == LPX_I_UNDEF || Status == LPX_I_NOFEAS) { NewSolution->Status = INFEASIBLE; return NewSolution; } else if (Status == LPX_I_FEAS) { NewSolution->Status = UNBOUNDED; return NewSolution; } else if (Status == LPX_I_OPT) { NewSolution->Status = SUCCESS; } else { delete NewSolution; FErrorFile() << "Problem status unrecognized." << endl; FlushErrorFile(); return NULL; } NewSolution->Objective = lpx_mip_obj_val(GLPKModel); NewSolution->SolutionData.resize(NumVariables); for (int i=0; i < NumVariables; i++) { NewSolution->SolutionData[i] = lpx_mip_col_val(GLPKModel, i+1); } } else if (ProbType == LP) { //First we check the basis matrix to ensure it is not sigular if (lpx_warm_up(GLPKModel) != LPX_E_OK) { lpx_adv_basis(GLPKModel); } Status = lpx_simplex(GLPKModel); if (Status == LPX_E_FAULT) { Status = lpx_warm_up(GLPKModel); if (Status == LPX_E_BADB) { /* the basis is invalid; build some valid basis */ lpx_adv_basis(GLPKModel); Status = lpx_simplex(GLPKModel); } } if (Status != LPX_E_OK) { FErrorFile() << "Failed to optimize problem." << endl; FlushErrorFile(); return NULL; } NewSolution = new OptSolutionData; Status = lpx_get_status(GLPKModel); if (Status == LPX_INFEAS || Status == LPX_NOFEAS || Status == LPX_UNDEF) { cout << "Model is infeasible" << endl; FErrorFile() << "Model is infeasible" << endl; FlushErrorFile(); NewSolution->Status = INFEASIBLE; return NewSolution; } else if (Status == LPX_FEAS || Status == LPX_UNBND) { cout << "Model is unbounded" << endl; FErrorFile() << "Model is unbounded" << endl; FlushErrorFile(); NewSolution->Status = UNBOUNDED; return NewSolution; } else if (Status == LPX_OPT) { NewSolution->Status = SUCCESS; } else { delete NewSolution; FErrorFile() << "Problem status unrecognized." << endl; FlushErrorFile(); return NULL; } NewSolution->Objective = lpx_get_obj_val(GLPKModel); NewSolution->SolutionData.resize(NumVariables); for (int i=0; i < NumVariables; i++) { NewSolution->SolutionData[i] = lpx_get_col_prim(GLPKModel, i+1); } } else { FErrorFile() << "Optimization problem type cannot be handled by GLPK solver." << endl; FlushErrorFile(); return NULL; } return NewSolution; }
void Gspan::lpboost(){ std::cout << "in lpboost" << std::endl; const char *out = "model"; //initialize unsigned int gnum = gdata.size(); weight.resize(gnum); std::fill(weight.begin(),weight.end(),1.0); corlab.resize(gnum); for(unsigned int gid=0;gid<gnum;++gid){ corlab[gid]=gdata[gid].class_label; } wbias=0.0; Hypothesis model; first_flag=true; need_to_cooc = false; cooc_is_opt = false; std::cout.setf(std::ios::fixed,std::ios::floatfield); std::cout.precision(8); //Initialize GLPK int* index = new int[gnum+2]; double* value = new double[gnum+2]; LPX* lp = lpx_create_prob(); lpx_add_cols(lp, gnum+1); // set u_1,...u_l, beta for (unsigned int i = 0; i < gnum; ++i){ lpx_set_col_bnds(lp, COL(i), LPX_DB, 0.0, 1/(nu*gnum)); lpx_set_obj_coef(lp, COL(i), 0); // u } lpx_set_col_bnds(lp, COL(gnum), LPX_FR, 0.0, 0.0); lpx_set_obj_coef(lp, COL(gnum), 1); // beta lpx_set_obj_dir(lp, LPX_MIN); //optimization direction: min objective lpx_add_rows(lp,1); // Add one row constraint s.t. sum_u == 1 for (unsigned int i = 0; i < gnum; ++i){ index[i+1] = COL(i); value[i+1] = 1; } lpx_set_mat_row(lp, ROW(0), gnum, index, value); lpx_set_row_bnds(lp, ROW(0), LPX_FX, 1, 1); double beta = 0.0; double margin = 0.0; //main loop for(unsigned int itr=0;itr < max_itr;++itr){ std::cout <<"itrator : "<<itr+1<<std::endl; if(itr==coocitr) need_to_cooc=true; opt_pat.gain=0.0;//gain init opt_pat.size=0; opt_pat.locsup.resize(0); pattern.resize(0); opt_pat.dfscode=""; Crun(); //std::cout<<opt_pat.gain<<" :"<<opt_pat.dfscode<<std::endl; std::vector <int> result (gnum); int _y; vector<int> locvec; std::string dfscode; if(cooc_is_opt == false){ _y = opt_pat.gain > 0 ? +1 :-1; locvec =opt_pat.locsup; dfscode=opt_pat.dfscode; }else{ _y = opt_pat_cooc.gain > 0 ? +1 :-1; locvec =opt_pat_cooc.locsup; dfscode=opt_pat_cooc.dfscode[0]+"\t"+opt_pat_cooc.dfscode[1];//=opt_pat_cooc.dfscode; } model.flag.resize(itr+1); model.flag[itr]=_y; std::fill (result.begin (), result.end(), -_y); for (unsigned int i = 0; i < locvec.size(); ++i) result[locvec[i]] = _y; double uyh = 0; for (unsigned int i = 0; i < gnum; ++i) { // summarizing hypotheses uyh += weight[i]*corlab[i]*result[i]; } std::cout << "Stopping criterion: " << uyh << "<=?" << beta << " + " << conv_epsilon << std::endl; if( (uyh <= beta + conv_epsilon ) ){ std::cout << "*********************************" << std::endl; std::cout << "Convergence ! at iteration: " << itr+1 << std::endl; std::cout << "*********************************" << std::endl; if(!end_of_cooc || need_to_cooc == true) break; need_to_cooc = true; } lpx_add_rows(lp,1); // Add one row constraint s.t. sum( uyh - beta ) <= 0 for (unsigned int i = 0; i < gnum; ++i){ index[i+1] = COL(i); value[i+1] = result[i] * corlab[i]; } index[gnum+1] = COL(gnum); value[gnum+1] = -1; lpx_set_mat_row(lp, ROW(itr+1), gnum+1, index, value); lpx_set_row_bnds(lp, ROW(itr+1), LPX_UP, 0.0, 0.0); model.weight.push_back(0); model.dfs_vector.push_back(dfscode); lpx_simplex(lp); beta = lpx_get_obj_val(lp); for (unsigned int i = 0; i < gnum; ++i){ double new_weight; new_weight = lpx_get_col_prim(lp, COL(i)); if(new_weight < 0) new_weight = 0; // weight > 0 weight[i] = new_weight; } margin = lpx_get_row_dual(lp, ROW(0)); double margin_error = 0.0; for (unsigned int i = 0; i < gnum; ++i) { // summarizing hypotheses if (corlab[i]*result[i] < margin){ ++margin_error; } } margin_error /= gnum; //next rule is estimated wbias = 0.0; for (unsigned int i = 0; i < gnum; ++i){ wbias += corlab[i] * weight[i]; } std::ofstream os (out); if (! os) { std::cerr << "FATAL: Cannot open output file: " << out << std::endl; return; } os.setf(std::ios::fixed,std::ios::floatfield); os.precision(12); for (unsigned int r = 0; r < itr; ++r){ model.weight[r] = - lpx_get_row_dual(lp, ROW(r+1)); if(model.weight[r] < 0) model.weight[r] = 0; // alpha > 0 os << model.flag[r] * model.weight[r] << "\t" << model.dfs_vector[r] << std::endl; std::cout << model.flag[r] * model.weight[r] << "\t" << model.dfs_vector[r] << std::endl; } std::cout << "After iteration " << itr+1 << std::endl; std::cout << "Margin: " << margin << std::endl; std::cout << "Margin Error: " << margin_error << std::endl; } std::cout << "end lpboost" << std::endl; }