void ipp_unload_sol(IPP *ipp, LPX *orig, int i_stat) { int i, j, k, len, *ind; double temp, *row_mipx, *val; xassert(ipp->orig_m == lpx_get_num_rows(orig)); xassert(ipp->orig_n == lpx_get_num_cols(orig)); xassert(ipp->orig_dir == lpx_get_obj_dir(orig)); /* all columns must be computed/recovered */ xassert(ipp->orig_n <= ipp->ncols); for (j = 1; j <= ipp->ncols; j++) xassert(ipp->col_stat[j]); /* compute values of auxiliary variables using known values of structural variables (columns) */ row_mipx = xcalloc(1+ipp->orig_m, sizeof(double)); ind = xcalloc(1+ipp->orig_n, sizeof(int)); val = xcalloc(1+ipp->orig_n, sizeof(double)); for (i = 1; i <= ipp->orig_m; i++) { len = lpx_get_mat_row(orig, i, ind, val); temp = 0.0; for (k = 1; k <= len; k++) temp += val[k] * ipp->col_mipx[ind[k]]; row_mipx[i] = temp; } xfree(ind); xfree(val); /* store solution components into the original problem object */ lpx_put_mip_soln(orig, i_stat, row_mipx, ipp->col_mipx); xfree(row_mipx); return; }
void lpp_load_sol(LPP *lpp, LPX *prob) { int i, j, ref, stat; double prim, dual; insist(lpp->m == lpx_get_num_rows(prob)); insist(lpp->n == lpx_get_num_cols(prob)); insist(lpp->orig_dir == lpx_get_obj_dir(prob)); insist(lpx_get_status(prob) != LPX_UNDEF); for (i = 1; i <= lpp->m; i++) { lpx_get_row_info(prob, i, &stat, &prim, &dual); ref = lpp->row_ref[i]; insist(1 <= ref && ref <= lpp->nrows); insist(lpp->row_stat[ref] == 0); lpp->row_stat[ref] = stat; lpp->row_prim[ref] = prim; lpp->row_dual[ref] = (lpp->orig_dir == LPX_MIN ? + dual : - dual); } for (j = 1; j <= lpp->n; j++) { lpx_get_col_info(prob, j, &stat, &prim, &dual); ref = lpp->col_ref[j]; insist(1 <= ref && ref <= lpp->ncols); insist(lpp->col_stat[ref] == 0); lpp->col_stat[ref] = stat; lpp->col_prim[ref] = prim; lpp->col_dual[ref] = (lpp->orig_dir == LPX_MIN ? + dual : - dual); } ufree(lpp->row_ref), lpp->row_ref = NULL; ufree(lpp->col_ref), lpp->col_ref = NULL; return; }
int CClp_load_warmstart(CClp *lp, CClp_warmstart *warm) { /* RESTORES the warmstart information in warm. */ int i, j, m, n, tagx, type, *rstat, *cstat; m = lpx_get_num_rows(lp->lp); n = lpx_get_num_cols(lp->lp); cstat = warm->cstat; rstat = warm->rstat; if (cstat == NULL || rstat == NULL) { print("CClp_load_warmstart: no basis information"); return 0; } for (j = 0; j < n; j++) { if (cstat[j] == IS_BASIC) tagx = LPX_BS; else { lpx_get_col_bnds(lp->lp, j+1, &type, NULL, NULL); switch (type) { case LPX_FR: tagx = LPX_NF; break; case LPX_LO: tagx = LPX_NL; break; case LPX_UP: tagx = LPX_NU; break; case LPX_DB: tagx = (cstat[j] == AT_UPPER ? LPX_NU : LPX_NL); break; case LPX_FX: tagx = LPX_NS; break; default: insist(type != type); } } lpx_set_col_stat(lp->lp, j+1, tagx); } for (i = 0; i < m; i++) { if (rstat[i] == IS_BASIC) tagx = LPX_BS; else { lpx_get_row_bnds(lp->lp, i+1, &type, NULL, NULL); switch (type) { case LPX_FR: tagx = LPX_NF; break; case LPX_LO: tagx = LPX_NL; break; case LPX_UP: tagx = LPX_NU; break; case LPX_DB: tagx = (rstat[i] == AT_UPPER ? LPX_NU : LPX_NL); break; case LPX_FX: tagx = LPX_NS; break; default: insist(type != type); } } lpx_set_row_stat(lp->lp, i+1, tagx); } return 0; }
void lpx_unscale_prob(LPX *lp) { int m = lpx_get_num_rows(lp); int n = lpx_get_num_cols(lp); int i, j; for (i = 1; i <= m; i++) lpx_set_rii(lp, i, 1.0); for (j = 1; j <= n; j++) lpx_set_sjj(lp, j, 1.0); return; }
int CClp_pi(CClp *lp, double *pi) { /* RETURNS the dual values on the constraints. - pi should be an array of length at least nrows. */ int nrows, i; nrows = lpx_get_num_rows(lp->lp); insist(nrows > 0); for (i = 0; i < nrows; i++) lpx_get_row_info(lp->lp, i+1, NULL, NULL, &pi[i]); return 0; }
int CClp_get_warmstart(CClp *lp, CClp_warmstart **warm) { /* SAVES information for efficiently resolving the current lp in warm, for example, basis or norm information. */ int i, j, tagx; CClp_free_warmstart(warm); (*warm) = umalloc(sizeof(CClp_warmstart)); (*warm)->ncols = 0; (*warm)->nrows = 0; (*warm)->cstat = NULL; (*warm)->rstat = NULL; (*warm)->ncols = lpx_get_num_cols(lp->lp); if ((*warm)->ncols == 0) { print("CClp_get_warmstart: no columns in LP"); CClp_free_warmstart(warm); return 1; } (*warm)->nrows = lpx_get_num_rows(lp->lp); if ((*warm)->nrows == 0) { print("CClp_get_warmstart: no rows in LP"); CClp_free_warmstart(warm); return 1; } (*warm)->cstat = ucalloc((*warm)->ncols, sizeof(int)); (*warm)->rstat = ucalloc((*warm)->nrows, sizeof(int)); for (i = 1; i <= (*warm)->nrows; i++) { lpx_get_row_info(lp->lp, i, &tagx, NULL, NULL); switch (tagx) { case LPX_BS: (*warm)->rstat[i-1] = IS_BASIC; break; case LPX_NL: (*warm)->rstat[i-1] = AT_LOWER; break; case LPX_NU: (*warm)->rstat[i-1] = AT_UPPER; break; case LPX_NS: (*warm)->rstat[i-1] = AT_LOWER; break; default: insist(tagx != tagx); } } for (j = 1; j <= (*warm)->ncols; j++) { lpx_get_col_info(lp->lp, j, &tagx, NULL, NULL); switch (tagx) { case LPX_BS: (*warm)->cstat[j-1] = IS_BASIC; break; case LPX_NL: (*warm)->cstat[j-1] = AT_LOWER; break; case LPX_NU: (*warm)->cstat[j-1] = AT_UPPER; break; case LPX_NS: (*warm)->cstat[j-1] = AT_LOWER; break; default: insist(tagx != tagx); } } return 0; }
int CClp_opt(CClp *lp, int method) { /* CALLS designated LP solution method. */ int stat, ret; if (MSGLEV >= 1) { int m = lpx_get_num_rows(lp->lp); int n = lpx_get_num_cols(lp->lp); int nz = lpx_get_num_nz(lp->lp); print("CClp_opt: %-11s m = %d; n = %d; nz = %d", method == CClp_METHOD_DUAL ? "(dual)" : "(primal)", m, n, nz); } lpx_set_int_parm(lp->lp, LPX_K_DUAL, method == CClp_METHOD_DUAL); switch (MSGLEV) { case 0: lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 0); lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 1000000); lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 1e6); break; case 1: lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 2); lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 200); lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 5.0); break; case 2: lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 3); lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 200); lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 0.0); break; default: insist(MSGLEV != MSGLEV); } ret = lpx_simplex(lp->lp); if (ret == LPX_E_FAULT) { if (MSGLEV >= 1) print("CClp_opt: restarting from advanced bas" "is..."); lpx_adv_basis(lp->lp); ret = lpx_simplex(lp->lp); } if (ret != LPX_E_OK) { print("CClp_opt: lpx_simplex failed; return code = %d", ret); ret = 1; goto done; } stat = lpx_get_status(lp->lp); if (stat == LPX_OPT) ret = 0; else if (stat == LPX_NOFEAS) ret = 2; else { print("CClp_opt: optimization status = %d", stat); ret = 1; } done: return ret; }
int CClp_delete_set_of_rows(CClp *lp, int *delstat) { /* DELETES the rows corresponding to 1 entries in delstat. - delstat is a 0/1 array having an entry for each row. */ int m = lpx_get_num_rows(lp->lp); int nrs = 0, i; int *num = ucalloc(1+m, sizeof(int)); for (i = 0; i < m; i++) if (delstat[i]) num[++nrs] = i+1; if (nrs > 0) lpx_del_rows(lp->lp, nrs, num); ufree(num); return 0; }
int GLPKAddConstraint(LinEquation* InEquation) { if (InEquation->QuadCoeff.size() > 0) { FErrorFile() << "GLPK solver cannot accept quadratic constraints." << endl; FlushErrorFile(); return FAIL; } if (GLPKModel == NULL) { FErrorFile() << "Could not add constraint because GLPK object does not exist." << endl; FlushErrorFile(); return FAIL; } int NumRows = lpx_get_num_rows(GLPKModel); if (InEquation->Index >= NumRows) { lpx_add_rows(GLPKModel, 1); } if (InEquation->EqualityType == EQUAL) { lpx_set_row_bnds(GLPKModel, InEquation->Index+1, LPX_FX, InEquation->RightHandSide, InEquation->RightHandSide); } else if (InEquation->EqualityType == GREATER) { lpx_set_row_bnds(GLPKModel, InEquation->Index+1, LPX_LO, InEquation->RightHandSide, InEquation->RightHandSide); } else if (InEquation->EqualityType == LESS) { lpx_set_row_bnds(GLPKModel, InEquation->Index+1, LPX_UP, InEquation->RightHandSide, InEquation->RightHandSide); } else { FErrorFile() << "Could not add constraint because the constraint type was not recognized." << endl; FlushErrorFile(); return FAIL; } int NumColumns = lpx_get_num_cols(GLPKModel); int* Indecies = new int[int(InEquation->Variables.size())+1]; double* Coeff = new double[int(InEquation->Variables.size())+1]; for (int i=0; i < int(InEquation->Variables.size()); i++) { if (InEquation->Variables[i]->Index < NumColumns) { Coeff[i+1] = InEquation->Coefficient[i]; Indecies[i+1] = InEquation->Variables[i]->Index+1; } else { FErrorFile() << "Variable index found in constraint is out of the range found in GLPK problem" << endl; FlushErrorFile(); return FAIL; } } lpx_set_mat_row(GLPKModel, InEquation->Index+1, int(InEquation->Variables.size()), Indecies, Coeff); delete [] Indecies; delete [] Coeff; return SUCCESS; }
void lpp_unload_sol(LPP *lpp, LPX *orig) { int i, j, k, m, n, typx, tagx; m = lpp->orig_m; n = lpp->orig_n; insist(m == lpx_get_num_rows(orig)); insist(n == lpx_get_num_cols(orig)); insist(lpp->orig_dir == lpx_get_obj_dir(orig)); /* check row and column statuses */ insist(m <= lpp->nrows); insist(n <= lpp->ncols); for (k = 1; k <= m+n; k++) { tagx = (k <= m ? lpp->row_stat[k] : lpp->col_stat[k-m]); if (tagx != LPX_BS) { if (k <= m) lpx_get_row_bnds(orig, k, &typx, NULL, NULL); else lpx_get_col_bnds(orig, k-m, &typx, NULL, NULL); switch (typx) { case LPX_FR: insist(tagx == LPX_NF); break; case LPX_LO: insist(tagx == LPX_NL); break; case LPX_UP: insist(tagx == LPX_NU); break; case LPX_DB: insist(tagx == LPX_NL || tagx == LPX_NU); break; case LPX_FX: insist(tagx == LPX_NS); break; default: insist(orig != orig); } } } /* if the original problem is maximization, change signs of dual values */ if (lpp->orig_dir == LPX_MAX) { for (i = 1; i <= m; i++) lpp->row_dual[i] = -lpp->row_dual[i]; for (j = 1; j <= n; j++) lpp->col_dual[j] = -lpp->col_dual[j]; } /* store solution components into the original problem object (it is assumed that the recovered solution is optimal) */ lpx_put_solution(orig, LPX_P_FEAS, LPX_D_FEAS, lpp->row_stat, lpp->row_prim, lpp->row_dual, lpp->col_stat, lpp->col_prim, lpp->col_dual); return; }
void lpx_eval_b_dual(LPX *lp, double row_dual[], double col_dual[]) { int i, j, k, m, n, len, *ind; double dj, *cB, *pi, *val; if (!lpx_is_b_avail(lp)) xfault("lpx_eval_b_dual: LP basis is not available\n"); m = lpx_get_num_rows(lp); n = lpx_get_num_cols(lp); /* store zero reduced costs of basic auxiliary and structural variables and build the vector cB of objective coefficients at basic variables */ cB = xcalloc(1+m, sizeof(double)); for (i = 1; i <= m; i++) { k = lpx_get_b_info(lp, i); /* xB[i] is k-th original variable */ xassert(1 <= k && k <= m+n); if (k <= m) { row_dual[k] = 0.0; cB[i] = 0.0; } else { col_dual[k-m] = 0.0; cB[i] = lpx_get_obj_coef(lp, k-m); } } /* solve the system B'*pi = cB to compute the vector pi */ pi = cB, lpx_btran(lp, pi); /* compute reduced costs of non-basic auxiliary variables */ for (i = 1; i <= m; i++) { if (lpx_get_row_stat(lp, i) != LPX_BS) row_dual[i] = - pi[i]; } /* compute reduced costs of non-basic structural variables */ ind = xcalloc(1+m, sizeof(int)); val = xcalloc(1+m, sizeof(double)); for (j = 1; j <= n; j++) { if (lpx_get_col_stat(lp, j) != LPX_BS) { dj = lpx_get_obj_coef(lp, j); len = lpx_get_mat_col(lp, j, ind, val); for (k = 1; k <= len; k++) dj += val[k] * pi[ind[k]]; col_dual[j] = dj; } } xfree(ind); xfree(val); xfree(cB); return; }
void lpx_scale_prob(LPX *lp) { /* scale LP/MIP problem data */ int m = lpx_get_num_rows(lp); int n = lpx_get_num_cols(lp); int sc_ord = 0, sc_max = 20; double sc_eps = 0.01; int i, j; double *R, *S; /* initialize R := I and S := I */ R = xcalloc(1+m, sizeof(double)); S = xcalloc(1+n, sizeof(double)); for (i = 1; i <= m; i++) R[i] = 1.0; for (j = 1; j <= n; j++) S[j] = 1.0; /* if the problem has no rows/columns, skip computations */ if (m == 0 || n == 0) goto skip; /* compute the scaling matrices R and S */ switch (lpx_get_int_parm(lp, LPX_K_SCALE)) { case 0: /* no scaling */ break; case 1: /* equilibration scaling */ eq_scal(m, n, lp, mat, R, S, sc_ord); break; case 2: /* geometric mean scaling */ gm_scal(m, n, lp, mat, R, S, sc_ord, sc_max, sc_eps); break; case 3: /* geometric mean scaling, then equilibration scaling */ gm_scal(m, n, lp, mat, R, S, sc_ord, sc_max, sc_eps); eq_scal(m, n, lp, mat, R, S, sc_ord); break; default: xassert(lp != lp); } skip: /* enter the scaling matrices R and S into the problem object and thereby perform implicit scaling */ for (i = 1; i <= m; i++) lpx_set_rii(lp, i, R[i]); for (j = 1; j <= n; j++) lpx_set_sjj(lp, j, S[j]); xfree(R); xfree(S); return; }
int CClp_addrows(CClp *lp, int newrows, int newnz, double *rhs, char *sense, int *rmatbeg, int *rmatind, double *rmatval) { /* ADDS the rows to the LP. - newrows is the number of rows to be added; - newnz is the number of nonzero coefficients in the new rows; - rhs is an array of the rhs values for the new rows; - sense is 'L', 'E', or 'G' for each of the new rows; - rmatbeg, rmatind, and rmatval give the coefficients of the new rows in sparse format. The arrays can be freed after the call. */ int i; lpx_add_rows(lp->lp, newrows); for (i = 0; i < newrows; i++) { int seqn, type, k, t; double lo, up; seqn = lpx_get_num_rows(lp->lp) - newrows + i + 1; switch (sense[i]) { case 'L': type = LPX_UP, lo = 0.0, up = rhs[i]; break; case 'E': type = LPX_FX, lo = up = rhs[i]; break; case 'G': type = LPX_LO, lo = rhs[i], up = 0.0; break; default: insist(sense[i] != sense[i]); } lpx_set_row_bnds(lp->lp, seqn, type, lo, up); insist(rmatbeg != NULL); insist(rmatind != NULL); insist(rmatval != NULL); insist(rmatbeg[0] == 0); t = (i < newrows-1 ? rmatbeg[i+1] : newnz); for (k = rmatbeg[i]; k < t; k++) rmatind[k]++; lpx_set_mat_row(lp->lp, seqn, t - rmatbeg[i], &rmatind[rmatbeg[i]] - 1, &rmatval[rmatbeg[i]] - 1); for (k = rmatbeg[i]; k < t; k++) rmatind[k]--; } return 0; }
void lpx_std_basis(LPX *lp) { int i, j, m, n, type; double lb, ub; /* all auxiliary variables are basic */ m = lpx_get_num_rows(lp); for (i = 1; i <= m; i++) lpx_set_row_stat(lp, i, LPX_BS); /* all structural variables are non-basic */ n = lpx_get_num_cols(lp); for (j = 1; j <= n; j++) { type = lpx_get_col_type(lp, j); lb = lpx_get_col_lb(lp, j); ub = lpx_get_col_ub(lp, j); if (type != LPX_DB || fabs(lb) <= fabs(ub)) lpx_set_col_stat(lp, j, LPX_NL); else lpx_set_col_stat(lp, j, LPX_NU); } return; }
static int mat(void *info, int k, int ndx[], double val[]) { /* this auxiliary routine obtains a required row or column of the original constraint matrix */ LPX *lp = info; int m = lpx_get_num_rows(lp); int n = lpx_get_num_cols(lp); int i, j, len; if (k > 0) { /* i-th row required */ i = +k; xassert(1 <= i && i <= m); len = lpx_get_mat_row(lp, i, ndx, val); } else { /* j-th column required */ j = -k; xassert(1 <= j && j <= n); len = lpx_get_mat_col(lp, j, ndx, val); } return len; }
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_reduce_form(LPX *lp, int len, int ind[], double val[], double _work[]) { int m = lpx_get_num_rows(lp); int n = lpx_get_num_cols(lp); int i, j, k, t; double *work = _work; /* allocate working array */ if (_work == NULL) work = ucalloc(1+m+n, sizeof(double)); /* convert the original linear form to dense format */ for (k = 1; k <= m+n; k++) work[k] = 0.0; for (t = 1; t <= len; t++) { k = ind[t]; if (!(1 <= k && k <= m+n)) fault("lpx_reduce_form: ind[%d] = %d; ordinal number out of" " range", t, k); work[k] += val[t]; } /* perform substitution */ for (i = 1; i <= m; i++) { /* substitute x[i] = a[i,1]*x[m+1] + ... + a[i,n]*x[m+n] */ if (work[i] == 0.0) continue; len = lpx_get_mat_row(lp, i, ind, val); for (t = 1; t <= len; t++) { j = ind[t]; work[m+j] += work[i] * val[t]; } } /* convert the resultant linear form to sparse format */ len = 0; for (j = 1; j <= n; j++) { if (work[m+j] == 0.0) continue; len++; ind[len] = j; val[len] = work[m+j]; } /* free working array */ if (_work == NULL) ufree(work); return len; }
int lpx_transform_col(LPX *lp, int len, int ind[], double val[]) { int i, m, t; double *a, *alfa; if (!lpx_is_b_avail(lp)) xfault("lpx_transform_col: LP basis is not available\n"); m = lpx_get_num_rows(lp); /* unpack the column to be transformed to the array a */ a = xcalloc(1+m, sizeof(double)); for (i = 1; i <= m; i++) a[i] = 0.0; if (!(0 <= len && len <= m)) xfault("lpx_transform_col: len = %d; invalid column length\n", len); for (t = 1; t <= len; t++) { i = ind[t]; if (!(1 <= i && i <= m)) xfault("lpx_transform_col: ind[%d] = %d; row index out of r" "ange\n", t, i); if (val[t] == 0.0) xfault("lpx_transform_col: val[%d] = 0; zero coefficient no" "t allowed\n", t); if (a[i] != 0.0) xfault("lpx_transform_col: ind[%d] = %d; duplicate row indi" "ces not allowed\n", t, i); a[i] = val[t]; } /* solve the system B*a = alfa to compute the vector alfa */ alfa = a, lpx_ftran(lp, alfa); /* store resultant coefficients */ len = 0; for (i = 1; i <= m; i++) { if (alfa[i] != 0.0) { len++; ind[len] = lpx_get_b_info(lp, i); val[len] = alfa[i]; } } xfree(a); return len; }
int CClp_new_row(CClp *lp, char sense, double rhs) { /* ADDS a new empty row to the lp. - sense is 'L', 'E', or 'G' for a <=, =, or >= constraint; - rhs is the right-hand side of the row. */ int seqn; lpx_add_rows(lp->lp, 1); seqn = lpx_get_num_rows(lp->lp); switch (sense) { case 'L': lpx_set_row_bnds(lp->lp, seqn, LPX_UP, 0.0, rhs); break; case 'E': lpx_set_row_bnds(lp->lp, seqn, LPX_FX, rhs, rhs); break; case 'G': lpx_set_row_bnds(lp->lp, seqn, LPX_LO, rhs, 0.0); break; default: insist(sense != sense); } return 0; }
int CClp_get_info(CClp *lp, CClp_info **info) { /* BUILDS information useful for efficiently answering questions about the status of rows and columns. */ int i, j, tagx; CClp_free_info(info); (*info) = umalloc(sizeof(CClp_info)); (*info)->ncols = 0; (*info)->nrows = 0; (*info)->cstat = NULL; (*info)->rstat = NULL; (*info)->ncols = lpx_get_num_cols(lp->lp); insist((*info)->ncols > 0); (*info)->nrows = lpx_get_num_rows(lp->lp); insist((*info)->nrows > 0); (*info)->cstat = ucalloc((*info)->ncols, sizeof(int)); (*info)->rstat = ucalloc((*info)->nrows, sizeof(int)); for (i = 1; i <= (*info)->nrows; i++) { lpx_get_row_info(lp->lp, i, &tagx, NULL, NULL); (*info)->rstat[i-1] = tagx == LPX_BS ? 1 : 0; } for (j = 1; j <= (*info)->ncols; j++) { lpx_get_col_info(lp->lp, j, &tagx, NULL, NULL); switch (tagx) { case LPX_BS: (*info)->cstat[j-1] = 0; break; case LPX_NL: (*info)->cstat[j-1] = 1; break; case LPX_NU: (*info)->cstat[j-1] = 2; break; case LPX_NS: (*info)->cstat[j-1] = 1; break; default: insist(tagx != tagx); } } return 0; }
int main(int argc, char *argv[]) { LPX *lp; MPL *mpl = NULL; int ret; double start; /* parse command line parameters */ parse_cmdline(argc, argv); /* remove all output files specified in the command line */ if (display != NULL) remove(display); if (out_sol != NULL) remove(out_sol); if (out_bnds != NULL) remove(out_bnds); if (out_mps != NULL) remove(out_mps); if (out_lpt != NULL) remove(out_lpt); if (out_txt != NULL) remove(out_txt); if (out_glp != NULL) remove(out_glp); /* read problem from the input file */ if (in_file == NULL) { print("No input file specified; try %s --help", argv[0]); exit(EXIT_FAILURE); } switch (format) { case 0: lp = lpx_read_mps(in_file); if (lp == NULL) { print("MPS file processing error"); exit(EXIT_FAILURE); } break; case 1: lp = lpx_read_lpt(in_file); if (lp == NULL) { print("CPLEX LP file processing error"); exit(EXIT_FAILURE); } break; case 2: #if 0 /* 01/VIII-2004 */ lp = lpx_read_model(in_file, in_data, display); if (lp == NULL) { print("Model processing error"); exit(EXIT_FAILURE); } #else /* initialize the translator database */ mpl = mpl_initialize(); /* read model section and optional data section */ ret = mpl_read_model(mpl, in_file, in_data != NULL); if (ret == 4) err: { print("Model processing error"); exit(EXIT_FAILURE); } insist(ret == 1 || ret == 2); /* read data section, if necessary */ if (in_data != NULL) { insist(ret == 1); ret = mpl_read_data(mpl, in_data); if (ret == 4) goto err; insist(ret == 2); } /* generate model */ ret = mpl_generate(mpl, display); if (ret == 4) goto err; /* extract problem instance */ lp = lpx_extract_prob(mpl); insist(lp != NULL); #endif if (lpx_get_num_rows(lp) == 0) { print("Problem has no rows"); exit(EXIT_FAILURE); } if (lpx_get_num_cols(lp) == 0) { print("Problem has no columns"); exit(EXIT_FAILURE); } break; case 3: lp = lpx_read_prob(in_file); if (lp == NULL) { print("GNU LP file processing error"); exit(EXIT_FAILURE); } break; default: insist(format != format); } /* change problem name (if required) */ if (newname != NULL) lpx_set_prob_name(lp, newname); /* change optimization direction (if required) */ if (dir != 0) lpx_set_obj_dir(lp, dir); /* write problem in MPS format (if required) */ if (out_mps != NULL) { lpx_set_int_parm(lp, LPX_K_MPSORIG, orig); ret = lpx_write_mps(lp, out_mps); if (ret != 0) { print("Unable to write problem in MPS format"); exit(EXIT_FAILURE); } } /* write problem in CPLEX LP format (if required) */ if (out_lpt != NULL) { lpx_set_int_parm(lp, LPX_K_LPTORIG, orig); ret = lpx_write_lpt(lp, out_lpt); if (ret != 0) { print("Unable to write problem in CPLEX LP format"); exit(EXIT_FAILURE); } } /* write problem in plain text format (if required) */ if (out_txt != NULL) { lpx_set_int_parm(lp, LPX_K_LPTORIG, orig); ret = lpx_print_prob(lp, out_txt); if (ret != 0) { print("Unable to write problem in plain text format"); exit(EXIT_FAILURE); } } /* write problem in GNU LP format (if required) */ if (out_glp != NULL) { ret = lpx_write_prob(lp, out_glp); if (ret != 0) { print("Unable to write problem in GNU LP format"); exit(EXIT_FAILURE); } } /* if only data check is required, skip computations */ if (check) goto skip; /* scale the problem data (if required) */ if (scale && (!presol || method == 1)) lpx_scale_prob(lp); /* build advanced initial basis (if required) */ if (method == 0 && basis && !presol) lpx_adv_basis(lp); /* set some control parameters, which might be changed in the command line */ lpx_set_int_parm(lp, LPX_K_PRICE, price); if (!relax) lpx_set_real_parm(lp, LPX_K_RELAX, 0.0); lpx_set_int_parm(lp, LPX_K_PRESOL, presol); lpx_set_int_parm(lp, LPX_K_BRANCH, branch); lpx_set_int_parm(lp, LPX_K_BTRACK, btrack); lpx_set_real_parm(lp, LPX_K_TMLIM, (double)tmlim); /* solve the problem */ start = utime(); switch (method) { case 0: if (nomip || lpx_get_class(lp) == LPX_LP) { ret = lpx_simplex(lp); if (presol && ret != LPX_E_OK && out_sol != NULL) print("If you need actual output for non-optimal solu" "tion, use --nopresol"); } else { method = 2; lpx_simplex(lp); if (!intopt) lpx_integer(lp); else lpx_intopt(lp); } break; case 1: if (nomip || lpx_get_class(lp) == LPX_LP) lpx_interior(lp); else { print("Interior point method is not able to solve MIP pr" "oblem; use --simplex"); exit(EXIT_FAILURE); } break; default: insist(method != method); } /* display statistics */ print("Time used: %.1f secs", utime() - start); print("Memory used: %.1fM (%d bytes)", (double)lib_env_ptr()->mem_tpeak / (double)(1024 * 1024), lib_env_ptr()->mem_tpeak); #if 1 /* 01/VIII-2004 */ if (mpl != NULL && mpl_has_solve_stmt(mpl)) { int n, j, round; /* store the solution to the translator database */ n = lpx_get_num_cols(lp); round = lpx_get_int_parm(lp, LPX_K_ROUND); lpx_set_int_parm(lp, LPX_K_ROUND, 1); switch (method) { case 0: for (j = 1; j <= n; j++) mpl_put_col_value(mpl, j, lpx_get_col_prim(lp, j)); break; case 1: for (j = 1; j <= n; j++) mpl_put_col_value(mpl, j, lpx_ipt_col_prim(lp, j)); break; case 2: for (j = 1; j <= n; j++) mpl_put_col_value(mpl, j, lpx_mip_col_val(lp, j)); break; default: insist(method != method); } lpx_set_int_parm(lp, LPX_K_ROUND, round); /* perform postsolving */ ret = mpl_postsolve(mpl, display); if (ret == 4) { print("Model postsolving error"); exit(EXIT_FAILURE); } insist(ret == 3); } #endif /* write problem solution found by the solver (if required) */ if (out_sol != NULL) { switch (method) { case 0: ret = lpx_print_sol(lp, out_sol); break; case 1: ret = lpx_print_ips(lp, out_sol); break; case 2: ret = lpx_print_mip(lp, out_sol); break; default: insist(method != method); } if (ret != 0) { print("Unable to write problem solution"); exit(EXIT_FAILURE); } } /* write sensitivity bounds information (if required) */ if (out_bnds != NULL) { if (method != 0) { print("Cannot write sensitivity bounds information for inte" "rior-point or MIP solution"); exit(EXIT_FAILURE); } ret = lpx_print_sens_bnds(lp, out_bnds); if (ret != 0) { print("Unable to write sensitivity bounds information"); exit(EXIT_FAILURE); } } skip: /* delete the problem object */ lpx_delete_prob(lp); #if 1 /* 01/VIII-2004 */ /* if the translator database exists, destroy it */ if (mpl != NULL) mpl_terminate(mpl); #endif /* check that no memory blocks are still allocated */ insist(lib_env_ptr()->mem_total == 0); insist(lib_env_ptr()->mem_count == 0); /* return to the control program */ return 0; }
void lpp_load_orig(LPP *lpp, LPX *orig) { LPPROW *row; LPPCOL *col, **map; int i, j, t, len, typx, *ndx; double lb, ub, temp, *c, *val; /* save some information about the original problem */ lpp->orig_m = lpx_get_num_rows(orig); lpp->orig_n = lpx_get_num_cols(orig); lpp->orig_nnz = lpx_get_num_nz(orig); lpp->orig_dir = lpx_get_obj_dir(orig); /* allocate working arrays */ c = ucalloc(1+lpp->orig_n, sizeof(double)); ndx = ucalloc(1+lpp->orig_n, sizeof(int)); val = ucalloc(1+lpp->orig_n, sizeof(double)); /* auxiliary variables (i.e. rows) in the original problem may have non-zero objective coefficients; so, we substitute these auxiliary variables into the objective function in order that it depends only on structural variables (i.e. columns); the resultant vector of objective coefficients is accumulated in the working array c */ for (j = 1; j <= lpp->orig_n; j++) c[j] = lpx_get_col_coef(orig, j); for (i = 1; i <= lpp->orig_m; i++) { /* obtain an objective coefficient at i-th row */ temp = lpx_get_row_coef(orig, i); /* substitute i-th row into the objective function */ if (temp != 0.0) { len = lpx_get_mat_row(orig, i, ndx, val); for (t = 1; t <= len; t++) c[ndx[t]] += val[t] * temp; } } /* copy rows of the original problem into the workspace; each row created in the workspace is assigned a reference number, which is its ordinal number in the original problem */ for (i = 1; i <= lpp->orig_m; i++) { lpx_get_row_bnds(orig, i, &typx, &lb, &ub); if (typx == LPX_FR || typx == LPX_UP) lb = -DBL_MAX; if (typx == LPX_FR || typx == LPX_LO) ub = +DBL_MAX; if (typx == LPX_FX) ub = lb; lpp_add_row(lpp, lb, ub); } /* copy columns of the original problem into the workspace; each column created in the workspace is assigned a reference number, which its ordinal number in the original problem */ for (j = 1; j <= lpp->orig_n; j++) { lpx_get_col_bnds(orig, j, &typx, &lb, &ub); if (typx == LPX_FR || typx == LPX_UP) lb = -DBL_MAX; if (typx == LPX_FR || typx == LPX_LO) ub = +DBL_MAX; if (typx == LPX_FX) ub = lb; lpp_add_col(lpp, lb, ub, c[j]); } /* copy the constant term of the original objective function */ lpp->c0 = lpx_get_obj_c0(orig); /* if the original problem is maximization, change the sign of the objective function, because the transformed problem to be processed by the presolver must be minimization */ if (lpp->orig_dir == LPX_MAX) { for (col = lpp->col_ptr; col != NULL; col = col->next) col->c = - col->c; lpp->c0 = - lpp->c0; } /* build an auxiliary array to map column ordinal numbers to the corresponding pointers */ insist(sizeof(LPPCOL *) <= sizeof(double)); map = (LPPCOL **)c; for (col = lpp->col_ptr; col != NULL; col = col->next) map[col->j] = col; /* copy the original constraint matrix into the workspace */ for (row = lpp->row_ptr; row != NULL; row = row->next) #if 1 { len = lpx_get_mat_row(orig, row->i, ndx, val); for (t = 1; t <= len; t++) lpp_add_aij(lpp, row, map[ndx[t]], val[t]); } #else /* 27/XI-2003 (the problem persists) */ { double big, eps; len = lpx_get_mat_row(orig, row->i, ndx, val); big = 0.0; for (t = 1; t <= len; t++) if (big < fabs(val[t])) big = fabs(val[t]); eps = 1e-10 * big; for (t = 1; t <= len; t++) { if (fabs(val[t]) < eps) continue; lpp_add_aij(lpp, row, map[ndx[t]], val[t]); } } #endif /* free working arrays */ ufree(c); ufree(ndx); ufree(val); return; }
int lpx_write_cpxlp(LPX *lp, const char *fname) { /* write problem data in CPLEX LP format */ FILE *fp; int nrows, ncols, i, j, t, len, typx, flag, kind, *ind; double lb, ub, temp, *val; char line[1023+1], term[1023+1], rname[255+1], cname[255+1]; print("lpx_write_cpxlp: writing problem data to `%s'...", fname); /* open the output text file */ fp = xfopen(fname, "w"); if (fp == NULL) { print("lpx_write_cpxlp: unable to create `%s' - %s", fname, strerror(errno)); goto fail; } /* determine the number of rows and columns */ nrows = lpx_get_num_rows(lp); ncols = lpx_get_num_cols(lp); /* the problem should contain at least one row and one column */ if (!(nrows > 0 && ncols > 0)) fault("lpx_write_cpxlp: problem has no rows/columns"); /* write problem name */ { const char *name = lpx_get_prob_name(lp); if (name == NULL) name = "Unknown"; fprintf(fp, "\\* Problem: %s *\\\n", name); fprintf(fp, "\n"); } /* allocate working arrays */ ind = xcalloc(1+ncols, sizeof(int)); val = xcalloc(1+ncols, sizeof(double)); /* write the objective function definition and the constraints section */ for (i = 0; i <= nrows; i++) { if (i == 0) { switch (lpx_get_obj_dir(lp)) { case LPX_MIN: fprintf(fp, "Minimize\n"); break; case LPX_MAX: fprintf(fp, "Maximize\n"); break; default: xassert(lp != lp); } } else if (i == 1) { temp = lpx_get_obj_coef(lp, 0); if (temp != 0.0) fprintf(fp, "\\* constant term = %.*g *\\\n", DBL_DIG, temp); fprintf(fp, "\n"); fprintf(fp, "Subject To\n"); } row_name(lp, i, rname); if (i == 0) { len = 0; for (j = 1; j <= ncols; j++) { temp = lpx_get_obj_coef(lp, j); if (temp != 0.0) len++, ind[len] = j, val[len] = temp; } } else { lpx_get_row_bnds(lp, i, &typx, &lb, &ub); if (typx == LPX_FR) continue; len = lpx_get_mat_row(lp, i, ind, val); } flag = 0; more: if (!flag) sprintf(line, " %s:", rname); else sprintf(line, " %*s ", strlen(rname), ""); for (t = 1; t <= len; t++) { col_name(lp, ind[t], cname); if (val[t] == +1.0) sprintf(term, " + %s", cname); else if (val[t] == -1.0) sprintf(term, " - %s", cname); else if (val[t] > 0.0) sprintf(term, " + %.*g %s", DBL_DIG, +val[t], cname); else if (val[t] < 0.0) sprintf(term, " - %.*g %s", DBL_DIG, -val[t], cname); else xassert(lp != lp); if (strlen(line) + strlen(term) > 72) fprintf(fp, "%s\n", line), line[0] = '\0'; strcat(line, term); } if (len == 0) { /* empty row */ sprintf(term, " 0 %s", col_name(lp, 1, cname)); strcat(line, term); } if (i > 0) { switch (typx) { case LPX_LO: case LPX_DB: sprintf(term, " >= %.*g", DBL_DIG, lb); break; case LPX_UP: sprintf(term, " <= %.*g", DBL_DIG, ub); break; case LPX_FX: sprintf(term, " = %.*g", DBL_DIG, lb); break; default: xassert(typx != typx); } if (strlen(line) + strlen(term) > 72) fprintf(fp, "%s\n", line), line[0] = '\0'; strcat(line, term); } fprintf(fp, "%s\n", line); if (i > 0 && typx == LPX_DB) { /* double-bounded row needs a copy for its upper bound */ flag = 1; typx = LPX_UP; goto more; } } /* free working arrays */ xfree(ind); xfree(val); /* write the bounds section */ flag = 0; for (j = 1; j <= ncols; j++) { col_name(lp, j, cname); lpx_get_col_bnds(lp, j, &typx, &lb, &ub); if (typx == LPX_LO && lb == 0.0) continue; if (!flag) { fprintf(fp, "\n"); fprintf(fp, "Bounds\n"); flag = 1; } switch (typx) { case LPX_FR: fprintf(fp, " %s free\n", cname); break; case LPX_LO: fprintf(fp, " %s >= %.*g\n", cname, DBL_DIG, lb); break; case LPX_UP: fprintf(fp, " %s <= %.*g\n", cname, DBL_DIG, ub); break; case LPX_DB: fprintf(fp, " %.*g <= %s <= %.*g\n", DBL_DIG, lb, cname, DBL_DIG, ub); break; case LPX_FX: fprintf(fp, " %s = %.*g\n", cname, DBL_DIG, lb); break; default: xassert(typx != typx); } } /* write the general section */ if (lpx_get_class(lp) == LPX_MIP) { flag = 0; for (j = 1; j <= ncols; j++) { kind = lpx_get_col_kind(lp, j); if (kind == LPX_CV) continue; xassert(kind == LPX_IV); if (!flag) { fprintf(fp, "\n"); fprintf(fp, "Generals\n"); flag = 1; } fprintf(fp, " %s\n", col_name(lp, j, cname)); } } /* write the end keyword */ fprintf(fp, "\n"); fprintf(fp, "End\n"); /* close the output text file */ fflush(fp); if (ferror(fp)) { print("lpx_write_cpxlp: write error on `%s' - %s", fname, strerror(errno)); goto fail; } xfclose(fp); /* return to the calling program */ return 0; fail: /* the operation failed */ if (fp != NULL) xfclose(fp); return 1; }
LPX *lpx_read_cpxlp(const char *fname) { /* read problem data in CPLEX LP format */ struct dsa _dsa, *dsa = &_dsa; if (setjmp(dsa->jump)) goto fail; dsa->lp = NULL; dsa->fname = fname; dsa->fp = NULL; dsa->count = 0; dsa->c = '\n'; dsa->token = T_EOF; dsa->image[0] = '\0'; dsa->imlen = 0; dsa->value = 0.0; dsa->n_max = 100; dsa->map = xcalloc(1+dsa->n_max, sizeof(int)); memset(&dsa->map[1], 0, dsa->n_max * sizeof(int)); dsa->ind = xcalloc(1+dsa->n_max, sizeof(int)); dsa->val = xcalloc(1+dsa->n_max, sizeof(double)); dsa->lb = xcalloc(1+dsa->n_max, sizeof(double)); dsa->ub = xcalloc(1+dsa->n_max, sizeof(double)); print("lpx_read_cpxlp: reading problem data from `%s'...", dsa->fname); dsa->fp = xfopen(dsa->fname, "r"); if (dsa->fp == NULL) { print("lpx_read_cpxlp: unable to open `%s' - %s", dsa->fname, strerror(errno)); goto fail; } dsa->lp = lpx_create_prob(); lpx_create_index(dsa->lp); #if 0 /* read very first character */ read_char(dsa); #endif /* scan very first token */ scan_token(dsa); /* parse definition of the objective function */ if (!(dsa->token == T_MINIMIZE || dsa->token == T_MAXIMIZE)) fatal(dsa, "`minimize' or `maximize' keyword missing"); parse_objective(dsa); /* parse constraints section */ if (dsa->token != T_SUBJECT_TO) fatal(dsa, "constraints section missing"); parse_constraints(dsa); /* parse optional bounds section */ if (dsa->token == T_BOUNDS) parse_bounds(dsa); /* parse optional general, integer, and binary sections */ while (dsa->token == T_GENERAL || dsa->token == T_INTEGER || dsa->token == T_BINARY) parse_integer(dsa); /* check for the keyword 'end' */ if (dsa->token == T_END) scan_token(dsa); else if (dsa->token == T_EOF) print("%s:%d: warning: keyword `end' missing", dsa->fname, dsa->count); else fatal(dsa, "symbol `%s' in wrong position", dsa->image); /* nothing must follow the keyword 'end' (except comments) */ if (dsa->token != T_EOF) fatal(dsa, "extra symbol(s) detected beyond `end'"); /* set bounds of variables */ { int j, type; double lb, ub; for (j = lpx_get_num_cols(dsa->lp); j >= 1; j--) { lb = dsa->lb[j]; ub = dsa->ub[j]; if (lb == +DBL_MAX) lb = 0.0; /* default lb */ if (ub == -DBL_MAX) ub = +DBL_MAX; /* default ub */ if (lb == -DBL_MAX && ub == +DBL_MAX) type = LPX_FR; else if (ub == +DBL_MAX) type = LPX_LO; else if (lb == -DBL_MAX) type = LPX_UP; else if (lb != ub) type = LPX_DB; else type = LPX_FX; lpx_set_col_bnds(dsa->lp, j, type, lb, ub); } } /* print some statistics */ { int m = lpx_get_num_rows(dsa->lp); int n = lpx_get_num_cols(dsa->lp); int nnz = lpx_get_num_nz(dsa->lp); print("lpx_read_cpxlp: %d row%s, %d column%s, %d non-zero%s", m, m == 1 ? "" : "s", n, n == 1 ? "" : "s", nnz, nnz == 1 ? "" : "s"); } if (lpx_get_class(dsa->lp) == LPX_MIP) { int ni = lpx_get_num_int(dsa->lp); int nb = lpx_get_num_bin(dsa->lp); char s[50]; 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); print("lpx_read_cpxlp: %d integer column%s, %s which %s binary" , ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); } print("lpx_read_cpxlp: %d lines were read", dsa->count); xfclose(dsa->fp); xfree(dsa->map); xfree(dsa->ind); xfree(dsa->val); xfree(dsa->lb); xfree(dsa->ub); lpx_delete_index(dsa->lp); lpx_order_matrix(dsa->lp); return dsa->lp; fail: if (dsa->lp != NULL) lpx_delete_prob(dsa->lp); if (dsa->fp != NULL) xfclose(dsa->fp); if (dsa->map != NULL) xfree(dsa->map); if (dsa->ind != NULL) xfree(dsa->ind); if (dsa->val != NULL) xfree(dsa->val); if (dsa->lb != NULL) xfree(dsa->lb); if (dsa->ub != NULL) xfree(dsa->ub); return NULL; }
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 lpx_print_mip(LPX *lp, const char *fname) { XFILE *fp; int what, round; #if 0 if (lpx_get_class(lp) != LPX_MIP) fault("lpx_print_mip: error -- not a MIP problem"); #endif xprintf( "lpx_print_mip: writing MIP problem solution to `%s'...\n", fname); fp = xfopen(fname, "w"); if (fp == NULL) { xprintf("lpx_print_mip: 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_int, nc_bin; nc = lpx_get_num_cols(lp); nc_int = lpx_get_num_int(lp); nc_bin = lpx_get_num_bin(lp); xfprintf(fp, "%-12s%d (%d integer, %d binary)\n", "Columns:", nc, nc_int, nc_bin); } /* 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_mip_status(lp); xfprintf(fp, "%-12s%s\n", "Status:", status == LPX_I_UNDEF ? "INTEGER UNDEFINED" : status == LPX_I_OPT ? "INTEGER OPTIMAL" : status == LPX_I_FEAS ? "INTEGER NON-OPTIMAL" : status == LPX_I_NOFEAS ? "INTEGER EMPTY" : "???"); } /* objective function */ { char *name; int dir; double mip_obj; name = (void *)lpx_get_obj_name(lp); dir = lpx_get_obj_dir(lp); mip_obj = lpx_mip_obj_val(lp); xfprintf(fp, "%-12s%s%s%.10g %s\n", "Objective:", name == NULL ? "" : name, name == NULL ? "" : " = ", mip_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 Activity Lower bound Upp" "er bound\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 kind, typx; double lb, ub, vx; if (what == 1) { name = lpx_get_row_name(lp, ij); if (name == NULL) name = ""; kind = LPX_CV; 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); vx = lpx_mip_row_val(lp, ij); lpx_set_int_parm(lp, LPX_K_ROUND, round); } else { name = lpx_get_col_name(lp, ij); if (name == NULL) name = ""; kind = lpx_get_col_kind(lp, ij); 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); vx = lpx_mip_col_val(lp, ij); 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 kind */ xfprintf(fp, "%s ", kind == LPX_CV ? " " : kind == LPX_IV ? "*" : "?"); /* row/column primal activity */ xfprintf(fp, "%13.6g", vx); /* row/column lower and upper bounds */ switch (typx) { case LPX_FR: break; case LPX_LO: xfprintf(fp, " %13.6g", lb); break; case LPX_UP: xfprintf(fp, " %13s %13.6g", "", ub); break; case LPX_DB: xfprintf(fp, " %13.6g %13.6g", lb, ub); break; case LPX_FX: xfprintf(fp, " %13.6g %13s", lb, "="); break; default: xassert(typx != typx); } /* end of line */ xfprintf(fp, "\n"); } } xfprintf(fp, "\n"); #if 1 if (lpx_mip_status(lp) != LPX_I_UNDEF) { int m = lpx_get_num_rows(lp); LPXKKT kkt; xfprintf(fp, "Integer feasibility conditions:\n\n"); lpx_check_int(lp, &kkt); xfprintf(fp, "INT.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, " SOLUTION IS WRONG\n"); break; } xfprintf(fp, "\n"); xfprintf(fp, "INT.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, " SOLUTION IS INFEASIBLE\n"); break; } xfprintf(fp, "\n"); } #endif xfprintf(fp, "End of output\n"); xfflush(fp); if (xferror(fp)) { xprintf("lpx_print_mip: 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 lpx_print_ips(LPX *lp, const char *fname) { XFILE *fp; int what, round; xprintf("lpx_print_ips: writing LP problem solution to `%s'...\n", fname); fp = xfopen(fname, "w"); if (fp == NULL) { xprintf("lpx_print_ips: 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_ipt_status(lp); xfprintf(fp, "%-12s%s\n", "Status:", status == LPX_T_UNDEF ? "INTERIOR UNDEFINED" : status == LPX_T_OPT ? "INTERIOR OPTIMAL" : "???"); } /* objective function */ { char *name; int dir; double obj; name = (void *)lpx_get_obj_name(lp); dir = lpx_get_obj_dir(lp); obj = lpx_ipt_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 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); vx = lpx_ipt_row_prim(lp, ij); dx = lpx_ipt_row_dual(lp, ij); 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); vx = lpx_ipt_col_prim(lp, ij); dx = lpx_ipt_col_dual(lp, ij); 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, ""); /* two positions are currently not used */ xfprintf(fp, " "); /* 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 */ xfprintf(fp, "%13.6g", dx); /* end of line */ xfprintf(fp, "\n"); } } xfprintf(fp, "\n"); xfprintf(fp, "End of output\n"); xfflush(fp); if (xferror(fp)) { xprintf("lpx_print_ips: 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 main(int argc, char *argv[]) { LPX *lp; MPL *mpl = NULL; int ret; ulong_t start; /* parse command line parameters */ parse_cmdline(argc, argv); /* set available memory limit */ if (memlim >= 0) lib_mem_limit(ulmul(ulset(0, 1048576), ulset(0, memlim))); /* remove all output files specified in the command line */ if (display != NULL) remove(display); if (out_bas != NULL) remove(out_bas); if (out_sol != NULL) remove(out_sol); if (out_bnds != NULL) remove(out_bnds); if (out_mps != NULL) remove(out_mps); if (out_freemps != NULL) remove(out_freemps); if (out_cpxlp != NULL) remove(out_cpxlp); if (out_txt != NULL) remove(out_txt); if (out_glp != NULL) remove(out_glp); if (log_file != NULL) remove(log_file); /* open hardcopy file, if necessary */ if (log_file != NULL) { if (lib_open_log(log_file)) { print("Unable to create log file"); exit(EXIT_FAILURE); } } /* read problem data from the input file */ if (in_file == NULL) { print("No input file specified; try %s --help", argv[0]); exit(EXIT_FAILURE); } switch (format) { case 0: lp = lpx_read_mps(in_file); if (lp == NULL) { print("MPS file processing error"); exit(EXIT_FAILURE); } orig = 1; break; case 1: lp = lpx_read_cpxlp(in_file); if (lp == NULL) { print("CPLEX LP file processing error"); exit(EXIT_FAILURE); } break; case 2: /* initialize the translator database */ mpl = mpl_initialize(); /* read model section and optional data section */ ret = mpl_read_model(mpl, in_file, in_data != NULL); if (ret == 4) err: { print("Model processing error"); exit(EXIT_FAILURE); } xassert(ret == 1 || ret == 2); /* read data section, if necessary */ if (in_data != NULL) { xassert(ret == 1); ret = mpl_read_data(mpl, in_data); if (ret == 4) goto err; xassert(ret == 2); } /* generate model */ ret = mpl_generate(mpl, display); if (ret == 4) goto err; /* extract problem instance */ lp = lpx_extract_prob(mpl); xassert(lp != NULL); break; case 3: lp = lpx_read_prob(in_file); if (lp == NULL) { print("GNU LP file processing error"); exit(EXIT_FAILURE); } break; case 4: lp = lpx_read_freemps(in_file); if (lp == NULL) { print("MPS file processing error"); exit(EXIT_FAILURE); } break; default: xassert(format != format); } /* order rows and columns of the constraint matrix */ lpx_order_matrix(lp); /* change problem name (if required) */ if (newname != NULL) lpx_set_prob_name(lp, newname); /* change optimization direction (if required) */ if (dir != 0) lpx_set_obj_dir(lp, dir); /* write problem in fixed MPS format (if required) */ if (out_mps != NULL) { lpx_set_int_parm(lp, LPX_K_MPSORIG, orig); ret = lpx_write_mps(lp, out_mps); if (ret != 0) { print("Unable to write problem in fixed MPS format"); exit(EXIT_FAILURE); } } /* write problem in free MPS format (if required) */ if (out_freemps != NULL) { ret = lpx_write_freemps(lp, out_freemps); if (ret != 0) { print("Unable to write problem in free MPS format"); exit(EXIT_FAILURE); } } /* write problem in CPLEX LP format (if required) */ if (out_cpxlp != NULL) { ret = lpx_write_cpxlp(lp, out_cpxlp); if (ret != 0) { print("Unable to write problem in CPLEX LP format"); exit(EXIT_FAILURE); } } /* write problem in plain text format (if required) */ if (out_txt != NULL) { lpx_set_int_parm(lp, LPX_K_LPTORIG, orig); ret = lpx_print_prob(lp, out_txt); if (ret != 0) { print("Unable to write problem in plain text format"); exit(EXIT_FAILURE); } } /* write problem in GNU LP format (if required) */ if (out_glp != NULL) { ret = lpx_write_prob(lp, out_glp); if (ret != 0) { print("Unable to write problem in GNU LP format"); exit(EXIT_FAILURE); } } /* if only data check is required, skip computations */ if (check) goto skip; /* scale the problem data (if required) */ if (scale && (!presol || method == 1)) lpx_scale_prob(lp); /* build initial LP basis */ if (method == 0 && !presol && in_bas == NULL) { switch (basis) { case 0: lpx_std_basis(lp); break; case 1: if (lpx_get_num_rows(lp) > 0 && lpx_get_num_cols(lp) > 0) lpx_adv_basis(lp); break; case 2: if (lpx_get_num_rows(lp) > 0 && lpx_get_num_cols(lp) > 0) lpx_cpx_basis(lp); break; default: xassert(basis != basis); } } /* or read initial basis from input text file in MPS format */ if (in_bas != NULL) { if (method != 0) { print("Initial LP basis is useless for interior-point solve" "r and therefore ignored"); goto nobs; } lpx_set_int_parm(lp, LPX_K_MPSORIG, orig); ret = lpx_read_bas(lp, in_bas); if (ret != 0) { print("Unable to read initial LP basis"); exit(EXIT_FAILURE); } if (presol) { presol = 0; print("LP presolver disabled because initial LP basis has b" "een provided"); } nobs: ; } /* set some control parameters, which might be changed in the command line */ lpx_set_int_parm(lp, LPX_K_BFTYPE, bf_type); lpx_set_int_parm(lp, LPX_K_PRICE, price); if (!relax) lpx_set_real_parm(lp, LPX_K_RELAX, 0.0); lpx_set_int_parm(lp, LPX_K_PRESOL, presol); lpx_set_int_parm(lp, LPX_K_BRANCH, branch); lpx_set_int_parm(lp, LPX_K_BTRACK, btrack); lpx_set_real_parm(lp, LPX_K_TMLIM, (double)tmlim); lpx_set_int_parm(lp, LPX_K_BINARIZE, binarize); lpx_set_int_parm(lp, LPX_K_USECUTS, use_cuts); /* solve the problem */ start = xtime(); switch (method) { case 0: if (nomip || lpx_get_class(lp) == LPX_LP) { ret = (!exact ? lpx_simplex(lp) : lpx_exact(lp)); if (xcheck) { if (!presol || ret == LPX_E_OK) lpx_exact(lp); else print("If you need checking final basis for non-op" "timal solution, use --nopresol"); } if (presol && ret != LPX_E_OK && (out_bas != NULL || out_sol != NULL)) print("If you need actual output for non-optimal solu" "tion, use --nopresol"); } else { method = 2; if (!intopt) { ret = (!exact ? lpx_simplex(lp) : lpx_exact(lp)); if (xcheck && (!presol || ret == LPX_E_OK)) lpx_exact(lp); lpx_integer(lp); } else lpx_intopt(lp); } break; case 1: if (nomip || lpx_get_class(lp) == LPX_LP) lpx_interior(lp); else { print("Interior-point method is not able to solve MIP pr" "oblem; use --simplex"); exit(EXIT_FAILURE); } break; default: xassert(method != method); } /* display statistics */ print("Time used: %.1f secs", xdifftime(xtime(), start)); { ulong_t tpeak; char buf[50]; lib_mem_usage(NULL, NULL, NULL, &tpeak); print("Memory used: %.1f Mb (%s bytes)", (4294967296.0 * tpeak.hi + tpeak.lo) / 1048576.0, ultoa(tpeak, buf, 10)); } if (mpl != NULL && mpl_has_solve_stmt(mpl)) { int n, j, round; /* store the solution to the translator database */ n = lpx_get_num_cols(lp); round = lpx_get_int_parm(lp, LPX_K_ROUND); lpx_set_int_parm(lp, LPX_K_ROUND, 1); switch (method) { case 0: for (j = 1; j <= n; j++) mpl_put_col_value(mpl, j, lpx_get_col_prim(lp, j)); break; case 1: for (j = 1; j <= n; j++) mpl_put_col_value(mpl, j, lpx_ipt_col_prim(lp, j)); break; case 2: for (j = 1; j <= n; j++) mpl_put_col_value(mpl, j, lpx_mip_col_val(lp, j)); break; default: xassert(method != method); } lpx_set_int_parm(lp, LPX_K_ROUND, round); /* perform postsolving */ ret = mpl_postsolve(mpl); if (ret == 4) { print("Model postsolving error"); exit(EXIT_FAILURE); } xassert(ret == 3); } /* write final LP basis (if required) */ if (out_bas != NULL) { lpx_set_int_parm(lp, LPX_K_MPSORIG, orig); ret = lpx_write_bas(lp, out_bas); if (ret != 0) { print("Unable to write final LP basis"); exit(EXIT_FAILURE); } } /* write problem solution found by the solver (if required) */ if (out_sol != NULL) { switch (method) { case 0: ret = lpx_print_sol(lp, out_sol); break; case 1: ret = lpx_print_ips(lp, out_sol); break; case 2: ret = lpx_print_mip(lp, out_sol); break; default: xassert(method != method); } if (ret != 0) { print("Unable to write problem solution"); exit(EXIT_FAILURE); } } /* write sensitivity bounds information (if required) */ if (out_bnds != NULL) { if (method != 0) { print("Cannot write sensitivity bounds information for inte" "rior-point or MIP solution"); exit(EXIT_FAILURE); } ret = lpx_print_sens_bnds(lp, out_bnds); if (ret != 0) { print("Unable to write sensitivity bounds information"); exit(EXIT_FAILURE); } } skip: /* delete the problem object */ lpx_delete_prob(lp); /* if the translator database exists, destroy it */ if (mpl != NULL) mpl_terminate(mpl); xassert(gmp_pool_count() == 0); gmp_free_mem(); /* close the hardcopy file */ if (log_file != NULL) lib_close_log(); /* check that no memory blocks are still allocated */ { int count; ulong_t total; lib_mem_usage(&count, NULL, &total, NULL); xassert(count == 0); xassert(total.lo == 0 && total.hi == 0); } /* free the library environment */ lib_free_env(); /* return to the control program */ return 0; }
int CClp_nrows(CClp *lp) { /* RETURNS the number of rows in the LP. */ return lpx_get_num_rows(lp->lp); }
int CClp_limited_dualopt(CClp *lp, int iterationlim, int *status, double *objupperlim) { /* CALLS the dual simplex method with a limit on the number of pivots. - upperbound it is used to cutoff the dual simplex method (when the objective value reaches upperbound); it can be NULL; - status returns the status of the optimization (it can be NULL). */ int stat, ret; insist(iterationlim == iterationlim); insist(objupperlim == objupperlim); if (MSGLEV >= 1) { int m = lpx_get_num_rows(lp->lp); int n = lpx_get_num_cols(lp->lp); int nz = lpx_get_num_nz(lp->lp); print("CClp_limited_dualopt: m = %d; n = %d; nz = %d", m, n, nz); } lpx_set_int_parm(lp->lp, LPX_K_DUAL, 1); switch (MSGLEV) { case 0: lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 0); lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 1000000); lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 1e6); break; case 1: lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 2); lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 200); lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 5.0); break; case 2: lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 3); lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 200); lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 0.0); break; default: insist(MSGLEV != MSGLEV); } ret = lpx_simplex(lp->lp); if (ret == LPX_E_FAULT) { if (MSGLEV >= 1) print("CClp_limited_dualopt: restarting from " "advanced basis..."); lpx_adv_basis(lp->lp); ret = lpx_simplex(lp->lp); } if (ret != LPX_E_OK) { print("CClp_limited_dualopt: lpx_simplex failed; return code =" " %d", ret); if (status) *status = CClp_FAILURE; ret = 1; goto done; } stat = lpx_get_status(lp->lp); if (stat == LPX_OPT) { if (status) *status = CClp_SUCCESS; ret = 0; } else if (stat == LPX_NOFEAS) { if (status) *status = CClp_INFEASIBLE; ret = 0; } else { print("CClp_limited_dualopt: optimization status = %d", stat); if (status) *status = CClp_FAILURE; ret = 1; } done: return ret; }