static void print_version(void) { /* print version information */ xprintf("GLPSOL: GLPK LP/MIP Solver %s\n", glp_version()); xprintf("\n"); xprintf("Copyright (C) 2008 Andrew Makhorin, Department for Appli" "ed Informatics,\n"); xprintf("Moscow Aviation Institute, Moscow, Russia. All rights re" "served.\n"); xprintf("\n"); xprintf("This program has ABSOLUTELY NO WARRANTY.\n"); xprintf("\n"); xprintf("This program is free software; you may re-distribute it " "under the terms\n"); xprintf("of the GNU General Public License version 3 or later.\n") ; return; }
/* * This is the main function. */ int main(int argc, char** argv) { int i; printf("GLPK version: %s\n", glp_version()); for (i = 1; i < 5; i++) { printf ("\nIteration %d", i); if (i & 1) { printf(", error expected to occur.\n"); } else { printf(", success expected.\n"); } if (runOptimizer(i)) { printf("An error has occured.\n"); } else { printf("Successful execution.\n"); } } return (EXIT_SUCCESS); }
int glp_intopt(glp_prob *P, const glp_iocp *parm) { /* solve MIP problem with the branch-and-bound method */ glp_iocp _parm; int i, j, ret; /* check problem object */ if (P == NULL || P->magic != GLP_PROB_MAGIC) xerror("glp_intopt: P = %p; invalid problem object\n", P); if (P->tree != NULL) xerror("glp_intopt: operation not allowed\n"); /* check control parameters */ if (parm == NULL) parm = &_parm, glp_init_iocp((glp_iocp *)parm); if (!(parm->msg_lev == GLP_MSG_OFF || parm->msg_lev == GLP_MSG_ERR || parm->msg_lev == GLP_MSG_ON || parm->msg_lev == GLP_MSG_ALL || parm->msg_lev == GLP_MSG_DBG)) xerror("glp_intopt: msg_lev = %d; invalid parameter\n", parm->msg_lev); if (!(parm->br_tech == GLP_BR_FFV || parm->br_tech == GLP_BR_LFV || parm->br_tech == GLP_BR_MFV || parm->br_tech == GLP_BR_DTH || parm->br_tech == GLP_BR_PCH)) xerror("glp_intopt: br_tech = %d; invalid parameter\n", parm->br_tech); if (!(parm->bt_tech == GLP_BT_DFS || parm->bt_tech == GLP_BT_BFS || parm->bt_tech == GLP_BT_BLB || parm->bt_tech == GLP_BT_BPH)) xerror("glp_intopt: bt_tech = %d; invalid parameter\n", parm->bt_tech); if (!(0.0 < parm->tol_int && parm->tol_int < 1.0)) xerror("glp_intopt: tol_int = %g; invalid parameter\n", parm->tol_int); if (!(0.0 < parm->tol_obj && parm->tol_obj < 1.0)) xerror("glp_intopt: tol_obj = %g; invalid parameter\n", parm->tol_obj); if (parm->tm_lim < 0) xerror("glp_intopt: tm_lim = %d; invalid parameter\n", parm->tm_lim); if (parm->out_frq < 0) xerror("glp_intopt: out_frq = %d; invalid parameter\n", parm->out_frq); if (parm->out_dly < 0) xerror("glp_intopt: out_dly = %d; invalid parameter\n", parm->out_dly); if (!(0 <= parm->cb_size && parm->cb_size <= 256)) xerror("glp_intopt: cb_size = %d; invalid parameter\n", parm->cb_size); if (!(parm->pp_tech == GLP_PP_NONE || parm->pp_tech == GLP_PP_ROOT || parm->pp_tech == GLP_PP_ALL)) xerror("glp_intopt: pp_tech = %d; invalid parameter\n", parm->pp_tech); if (parm->mip_gap < 0.0) xerror("glp_intopt: mip_gap = %g; invalid parameter\n", parm->mip_gap); if (!(parm->mir_cuts == GLP_ON || parm->mir_cuts == GLP_OFF)) xerror("glp_intopt: mir_cuts = %d; invalid parameter\n", parm->mir_cuts); if (!(parm->gmi_cuts == GLP_ON || parm->gmi_cuts == GLP_OFF)) xerror("glp_intopt: gmi_cuts = %d; invalid parameter\n", parm->gmi_cuts); if (!(parm->cov_cuts == GLP_ON || parm->cov_cuts == GLP_OFF)) xerror("glp_intopt: cov_cuts = %d; invalid parameter\n", parm->cov_cuts); if (!(parm->clq_cuts == GLP_ON || parm->clq_cuts == GLP_OFF)) xerror("glp_intopt: clq_cuts = %d; invalid parameter\n", parm->clq_cuts); if (!(parm->presolve == GLP_ON || parm->presolve == GLP_OFF)) xerror("glp_intopt: presolve = %d; invalid parameter\n", parm->presolve); if (!(parm->binarize == GLP_ON || parm->binarize == GLP_OFF)) xerror("glp_intopt: binarize = %d; invalid parameter\n", parm->binarize); if (!(parm->fp_heur == GLP_ON || parm->fp_heur == GLP_OFF)) xerror("glp_intopt: fp_heur = %d; invalid parameter\n", parm->fp_heur); #if 1 /* 28/V-2010 */ if (!(parm->alien == GLP_ON || parm->alien == GLP_OFF)) xerror("glp_intopt: alien = %d; invalid parameter\n", parm->alien); #endif #if 0 /* 11/VII-2013 */ /* integer solution is currently undefined */ P->mip_stat = GLP_UNDEF; P->mip_obj = 0.0; #else if (!parm->use_sol) P->mip_stat = GLP_UNDEF; if (P->mip_stat == GLP_NOFEAS) P->mip_stat = GLP_UNDEF; if (P->mip_stat == GLP_UNDEF) P->mip_obj = 0.0; else if (P->mip_stat == GLP_OPT) P->mip_stat = GLP_FEAS; #endif /* check bounds of double-bounded variables */ for (i = 1; i <= P->m; i++) { GLPROW *row = P->row[i]; if (row->type == GLP_DB && row->lb >= row->ub) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_intopt: row %d: lb = %g, ub = %g; incorrect" " bounds\n", i, row->lb, row->ub); ret = GLP_EBOUND; goto done; } } for (j = 1; j <= P->n; j++) { GLPCOL *col = P->col[j]; if (col->type == GLP_DB && col->lb >= col->ub) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_intopt: column %d: lb = %g, ub = %g; incorr" "ect bounds\n", j, col->lb, col->ub); ret = GLP_EBOUND; goto done; } } /* bounds of all integer variables must be integral */ for (j = 1; j <= P->n; j++) { GLPCOL *col = P->col[j]; if (col->kind != GLP_IV) continue; if (col->type == GLP_LO || col->type == GLP_DB) { if (col->lb != floor(col->lb)) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_intopt: integer column %d has non-intege" "r lower bound %g\n", j, col->lb); ret = GLP_EBOUND; goto done; } } if (col->type == GLP_UP || col->type == GLP_DB) { if (col->ub != floor(col->ub)) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_intopt: integer column %d has non-intege" "r upper bound %g\n", j, col->ub); ret = GLP_EBOUND; goto done; } } if (col->type == GLP_FX) { if (col->lb != floor(col->lb)) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_intopt: integer column %d has non-intege" "r fixed value %g\n", j, col->lb); ret = GLP_EBOUND; goto done; } } } /* solve MIP problem */ if (parm->msg_lev >= GLP_MSG_ALL) { int ni = glp_get_num_int(P); int nb = glp_get_num_bin(P); char s[50]; xprintf("GLPK Integer Optimizer, v%s\n", glp_version()); xprintf("%d row%s, %d column%s, %d non-zero%s\n", P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", P->nnz, P->nnz == 1 ? "" : "s"); if (nb == 0) strcpy(s, "none of"); else if (ni == 1 && nb == 1) strcpy(s, ""); else if (nb == 1) strcpy(s, "one of"); else if (nb == ni) strcpy(s, "all of"); else sprintf(s, "%d of", nb); xprintf("%d integer variable%s, %s which %s binary\n", ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); } #if 1 /* 28/V-2010 */ if (parm->alien) { /* use alien integer optimizer */ ret = _glp_intopt1(P, parm); goto done; } #endif if (!parm->presolve) #if 0 /* 11/VII-2013 */ ret = solve_mip(P, parm); #else ret = solve_mip(P, parm, P, NULL); #endif else
int glp_print_ranges(glp_prob *P, int len, const int list[], int flags, const char *fname) { /* print sensitivity analysis report */ glp_file *fp = NULL; GLPROW *row; GLPCOL *col; int m, n, pass, k, t, numb, type, stat, var1, var2, count, page, ret; double lb, ub, slack, coef, prim, dual, value1, value2, coef1, coef2, obj1, obj2; const char *name, *limit; char buf[13+1]; /* sanity checks */ if (P == NULL || P->magic != GLP_PROB_MAGIC) xerror("glp_print_ranges: P = %p; invalid problem object\n", P); m = P->m, n = P->n; if (len < 0) xerror("glp_print_ranges: len = %d; invalid list length\n", len); if (len > 0) { if (list == NULL) xerror("glp_print_ranges: list = %p: invalid parameter\n", list); for (t = 1; t <= len; t++) { k = list[t]; if (!(1 <= k && k <= m+n)) xerror("glp_print_ranges: list[%d] = %d; row/column numb" "er out of range\n", t, k); } } if (flags != 0) xerror("glp_print_ranges: flags = %d; invalid parameter\n", flags); if (fname == NULL) xerror("glp_print_ranges: fname = %p; invalid parameter\n", fname); if (glp_get_status(P) != GLP_OPT) { xprintf("glp_print_ranges: optimal basic solution required\n"); ret = 1; goto done; } if (!glp_bf_exists(P)) { xprintf("glp_print_ranges: basis factorization required\n"); ret = 2; goto done; } /* start reporting */ xprintf("Write sensitivity analysis report to '%s'...\n", fname); fp = glp_open(fname, "w"); if (fp == NULL) { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); ret = 3; goto done; } page = count = 0; for (pass = 1; pass <= 2; pass++) for (t = 1; t <= (len == 0 ? m+n : len); t++) { if (t == 1) count = 0; k = (len == 0 ? t : list[t]); if (pass == 1 && k > m || pass == 2 && k <= m) continue; if (count == 0) { xfprintf(fp, "GLPK %-4s - SENSITIVITY ANALYSIS REPORT%73sPa" "ge%4d\n", glp_version(), "", ++page); xfprintf(fp, "\n"); xfprintf(fp, "%-12s%s\n", "Problem:", P->name == NULL ? "" : P->name); xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", P->obj == NULL ? "" : P->obj, P->obj == NULL ? "" : " = ", P->obj_val, P->dir == GLP_MIN ? "MINimum" : P->dir == GLP_MAX ? "MAXimum" : "???"); xfprintf(fp, "\n"); xfprintf(fp, "%6s %-12s %2s %13s %13s %13s %13s %13s %13s " "%s\n", "No.", pass == 1 ? "Row name" : "Column name", "St", "Activity", pass == 1 ? "Slack" : "Obj coef", "Lower bound", "Activity", "Obj coef", "Obj value at", "Limiting"); xfprintf(fp, "%6s %-12s %2s %13s %13s %13s %13s %13s %13s " "%s\n", "", "", "", "", "Marginal", "Upper bound", "range", "range", "break point", "variable"); xfprintf(fp, "------ ------------ -- ------------- --------" "----- ------------- ------------- ------------- ------" "------- ------------\n"); } if (pass == 1) { numb = k; xassert(1 <= numb && numb <= m); row = P->row[numb]; name = row->name; type = row->type; lb = glp_get_row_lb(P, numb); ub = glp_get_row_ub(P, numb); coef = 0.0; stat = row->stat; prim = row->prim; if (type == GLP_FR) slack = - prim; else if (type == GLP_LO) slack = lb - prim; else if (type == GLP_UP || type == GLP_DB || type == GLP_FX) slack = ub - prim; dual = row->dual; } else { numb = k - m; xassert(1 <= numb && numb <= n); col = P->col[numb]; name = col->name; lb = glp_get_col_lb(P, numb); ub = glp_get_col_ub(P, numb); coef = col->coef; stat = col->stat; prim = col->prim; slack = 0.0; dual = col->dual; } if (stat != GLP_BS) { glp_analyze_bound(P, k, &value1, &var1, &value2, &var2); if (stat == GLP_NF) coef1 = coef2 = coef; else if (stat == GLP_NS) coef1 = -DBL_MAX, coef2 = +DBL_MAX; else if (stat == GLP_NL && P->dir == GLP_MIN || stat == GLP_NU && P->dir == GLP_MAX) coef1 = coef - dual, coef2 = +DBL_MAX; else coef1 = -DBL_MAX, coef2 = coef - dual; if (value1 == -DBL_MAX) { if (dual < -1e-9) obj1 = +DBL_MAX; else if (dual > +1e-9) obj1 = -DBL_MAX; else obj1 = P->obj_val; } else obj1 = P->obj_val + dual * (value1 - prim); if (value2 == +DBL_MAX) { if (dual < -1e-9) obj2 = -DBL_MAX; else if (dual > +1e-9) obj2 = +DBL_MAX; else obj2 = P->obj_val; } else obj2 = P->obj_val + dual * (value2 - prim); } else { glp_analyze_coef(P, k, &coef1, &var1, &value1, &coef2, &var2, &value2); if (coef1 == -DBL_MAX) { if (prim < -1e-9) obj1 = +DBL_MAX; else if (prim > +1e-9) obj1 = -DBL_MAX; else obj1 = P->obj_val; } else obj1 = P->obj_val + (coef1 - coef) * prim; if (coef2 == +DBL_MAX) { if (prim < -1e-9) obj2 = -DBL_MAX; else if (prim > +1e-9) obj2 = +DBL_MAX; else obj2 = P->obj_val; } else obj2 = P->obj_val + (coef2 - coef) * prim; } /*** first line ***/ /* row/column number */ xfprintf(fp, "%6d", numb); /* row/column name */ xfprintf(fp, " %-12.12s", name == NULL ? "" : name); if (name != NULL && strlen(name) > 12) xfprintf(fp, "%s\n%6s %12s", name+12, "", ""); /* row/column status */ xfprintf(fp, " %2s", stat == GLP_BS ? "BS" : stat == GLP_NL ? "NL" : stat == GLP_NU ? "NU" : stat == GLP_NF ? "NF" : stat == GLP_NS ? "NS" : "??"); /* row/column activity */ xfprintf(fp, " %s", format(buf, prim)); /* row slack, column objective coefficient */ xfprintf(fp, " %s", format(buf, k <= m ? slack : coef)); /* row/column lower bound */ xfprintf(fp, " %s", format(buf, lb)); /* row/column activity range */ xfprintf(fp, " %s", format(buf, value1)); /* row/column objective coefficient range */ xfprintf(fp, " %s", format(buf, coef1)); /* objective value at break point */ xfprintf(fp, " %s", format(buf, obj1)); /* limiting variable name */ if (var1 != 0) { if (var1 <= m) limit = glp_get_row_name(P, var1); else limit = glp_get_col_name(P, var1 - m); if (limit != NULL) xfprintf(fp, " %s", limit); } xfprintf(fp, "\n"); /*** second line ***/ xfprintf(fp, "%6s %-12s %2s %13s", "", "", "", ""); /* row/column reduced cost */ xfprintf(fp, " %s", format(buf, dual)); /* row/column upper bound */ xfprintf(fp, " %s", format(buf, ub)); /* row/column activity range */ xfprintf(fp, " %s", format(buf, value2)); /* row/column objective coefficient range */ xfprintf(fp, " %s", format(buf, coef2)); /* objective value at break point */ xfprintf(fp, " %s", format(buf, obj2)); /* limiting variable name */ if (var2 != 0) { if (var2 <= m) limit = glp_get_row_name(P, var2); else limit = glp_get_col_name(P, var2 - m); if (limit != NULL) xfprintf(fp, " %s", limit); } xfprintf(fp, "\n"); xfprintf(fp, "\n"); /* print 10 items per page */ count = (count + 1) % 10; } xfprintf(fp, "End of report\n"); #if 0 /* FIXME */ xfflush(fp); #endif if (glp_ioerr(fp)) { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); ret = 4; goto done; } ret = 0; done: if (fp != NULL) glp_close(fp); return ret; }
int glp_simplex(glp_prob *P, const glp_smcp *parm) { /* solve LP problem with the simplex method */ glp_smcp _parm; int i, j, ret; /* check problem object */ if (P == NULL || P->magic != GLP_PROB_MAGIC) xerror("glp_simplex: P = %p; invalid problem object\n", P); if (P->tree != NULL && P->tree->reason != 0) xerror("glp_simplex: operation not allowed\n"); /* check control parameters */ if (parm == NULL) parm = &_parm, glp_init_smcp((glp_smcp *)parm); if (!(parm->msg_lev == GLP_MSG_OFF || parm->msg_lev == GLP_MSG_ERR || parm->msg_lev == GLP_MSG_ON || parm->msg_lev == GLP_MSG_ALL || parm->msg_lev == GLP_MSG_DBG)) xerror("glp_simplex: msg_lev = %d; invalid parameter\n", parm->msg_lev); if (!(parm->meth == GLP_PRIMAL || parm->meth == GLP_DUALP || parm->meth == GLP_DUAL)) xerror("glp_simplex: meth = %d; invalid parameter\n", parm->meth); if (!(parm->pricing == GLP_PT_STD || parm->pricing == GLP_PT_PSE)) xerror("glp_simplex: pricing = %d; invalid parameter\n", parm->pricing); if (!(parm->r_test == GLP_RT_STD || parm->r_test == GLP_RT_HAR)) xerror("glp_simplex: r_test = %d; invalid parameter\n", parm->r_test); if (!(0.0 < parm->tol_bnd && parm->tol_bnd < 1.0)) xerror("glp_simplex: tol_bnd = %g; invalid parameter\n", parm->tol_bnd); if (!(0.0 < parm->tol_dj && parm->tol_dj < 1.0)) xerror("glp_simplex: tol_dj = %g; invalid parameter\n", parm->tol_dj); if (!(0.0 < parm->tol_piv && parm->tol_piv < 1.0)) xerror("glp_simplex: tol_piv = %g; invalid parameter\n", parm->tol_piv); if (parm->it_lim < 0) xerror("glp_simplex: it_lim = %d; invalid parameter\n", parm->it_lim); if (parm->tm_lim < 0) xerror("glp_simplex: tm_lim = %d; invalid parameter\n", parm->tm_lim); if (parm->out_frq < 1) xerror("glp_simplex: out_frq = %d; invalid parameter\n", parm->out_frq); if (parm->out_dly < 0) xerror("glp_simplex: out_dly = %d; invalid parameter\n", parm->out_dly); if (!(parm->presolve == GLP_ON || parm->presolve == GLP_OFF)) xerror("glp_simplex: presolve = %d; invalid parameter\n", parm->presolve); /* basic solution is currently undefined */ P->pbs_stat = P->dbs_stat = GLP_UNDEF; P->obj_val = 0.0; P->some = 0; /* check bounds of double-bounded variables */ for (i = 1; i <= P->m; i++) { GLPROW *row = P->row[i]; if (row->type == GLP_DB && row->lb >= row->ub) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_simplex: row %d: lb = %g, ub = %g; incorrec" "t bounds\n", i, row->lb, row->ub); ret = GLP_EBOUND; goto done; } } for (j = 1; j <= P->n; j++) { GLPCOL *col = P->col[j]; if (col->type == GLP_DB && col->lb >= col->ub) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_simplex: column %d: lb = %g, ub = %g; incor" "rect bounds\n", j, col->lb, col->ub); ret = GLP_EBOUND; goto done; } } /* solve LP problem */ if (parm->msg_lev >= GLP_MSG_ALL) { xprintf("GLPK Simplex Optimizer, v%s\n", glp_version()); xprintf("%d row%s, %d column%s, %d non-zero%s\n", P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", P->nnz, P->nnz == 1 ? "" : "s"); } if (P->nnz == 0) trivial_lp(P, parm), ret = 0; else if (!parm->presolve) ret = solve_lp(P, parm); else ret = preprocess_and_solve_lp(P, parm); done: /* return to the application program */ return ret; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if(strcmp(glp_version(),"4.18")<0){ mexErrMsgTxt("This MEX interface is compatible only with GLPK version 4.18 or higher."); } if (nrhs != 9){ mexPrintf("MEX interface to GLPK Version %s\n",glp_version()); mexPrintf("Internal interface for the GNU GLPK library.\n"); mexPrintf("You should use the 'glpk' function instead.\n\n"); mexPrintf("SYNTAX: [xopt, fmin, status, extra] = glpkcc(c, a, b, lb, ub, ctype, vartype, sense, param)\n"); return; } //-- 1nd Input. A column array containing the objective function //-- coefficients. int mrowsc = mxGetM(C_IN); double *c=mxGetPr(C_IN); if (c == NULL) mexErrMsgTxt("glpkcc: invalid value of C"); //-- 2nd Input. A matrix containing the constraints coefficients. // If matrix A is NOT a sparse matrix double *A = mxGetPr(A_IN); // get the matrix if(A==NULL) mexErrMsgTxt("glpkcc: invalid value of A"); int mrowsA = mxGetM(A_IN); int *rn; int *cn; double *a; int nz = 0; if(!mxIsSparse(A_IN)){ rn=(int *)mxCalloc(mrowsA*mrowsc+1,sizeof(int)); cn=(int *)mxCalloc(mrowsA*mrowsc+1,sizeof(int)); a=(double *)mxCalloc(mrowsA*mrowsc+1,sizeof(double)); for (int i = 0; i < mrowsA; i++){ for (int j = 0; j < mrowsc; j++){ if (A[i+j*mrowsA] != 0){ nz++; rn[nz] = i + 1; cn[nz] = j + 1; a[nz] = A[i+j*mrowsA]; } } } }else{ /* NOTE: nnz is the actual number of nonzeros and is stored as the last element of the jc array where the size of the jc array is the number of columns + 1 */ nz = *(mxGetJc(A_IN) + mrowsc); int *jc = mxGetJc(A_IN); int *ir = mxGetIr(A_IN); double *pr = mxGetPr(A_IN); rn=(int *)mxCalloc(nz+1,sizeof(int)); cn=(int *)mxCalloc(nz+1,sizeof(int)); a=(double *)mxCalloc(nz+1,sizeof(double)); int nelc,count,row; count=0; row=0; for(int i=1;i<=mrowsc;i++){ nelc=jc[i]-jc[i-1]; for(int j=0;j<nelc;j++){ count++; rn[count]=ir[row]+1; cn[count]=i; a[count]=pr[row]; row++; } } } //-- 3rd Input. A column array containing the right-hand side value // for each constraint in the constraint matrix. double *b = mxGetPr(B_IN); if (b==NULL) mexErrMsgTxt("glpkcc: invalid value of b"); //-- 4th Input. An array of length mrowsc containing the lower //-- bound on each of the variables. double *lb = mxGetPr(LB_IN); if (lb==NULL) mexErrMsgTxt("glpkcc: invalid value of lb"); //-- LB argument, default: Free int *freeLB=(int *)mxCalloc(mrowsc,sizeof(int)); for (int i = 0; i < mrowsc; i++) { if (lb[i]==-mxGetInf()){ freeLB[i] = 1; }else freeLB[i] = 0; } //-- 5th Input. An array of at least length numcols containing the upper //-- bound on each of the variables. double *ub = mxGetPr(UB_IN); if (ub==NULL) mexErrMsgTxt("glpkcc: invalid value of ub"); int *freeUB=(int *)mxCalloc(mrowsc,sizeof(int)); for (int i = 0; i < mrowsc; i++) { if (ub[i]==mxGetInf()) { freeUB[i] = 1; }else freeUB[i] = 0; } //-- 6th Input. A column array containing the sense of each constraint //-- in the constraint matrix. int size = mxGetNumberOfElements(CTYPE_IN) + 1; if (size==0) mexErrMsgTxt("glpkcc: invalid value of ctype"); /* Allocate enough memory to hold the converted string. */ char *ctype =(char *)mxCalloc(size, sizeof (char)); /* Copy the string data from string_array_ptr and place it into buf. */ if (mxGetString(CTYPE_IN, ctype, size) != 0) mexErrMsgTxt("Could not convert string data."); //-- 7th Input. A column array containing the types of the variables. size = mxGetNumberOfElements(VARTYPE_IN)+1; char *vtype = (char *)mxCalloc(size, sizeof (char)); int *vartype = (int *)mxCalloc(size, sizeof (int)); if (size==0) mexErrMsgTxt("glpkcc: invalid value of vartype"); // Copy the string data from string_array_ptr and place it into buf. if (mxGetString(VARTYPE_IN, vtype, size) != 0) mexErrMsgTxt("Could not convert string data."); int isMIP = 0; for (int i = 0; i < mrowsc ; i++) { switch (vtype[i]){ case 'I': vartype[i] = GLP_IV; isMIP = 1; break; case 'B': vartype[i] = GLP_BV; isMIP = 1; break; default: vartype[i] = GLP_CV; } } //-- 8th Input. Sense of optimization. int sense; double *tmp = mxGetPr(SENSE_IN); if (*tmp >= 0) sense = 1; else sense = -1; //-- 9th Input. A structure containing the control parameters. //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //-- Integer parameters //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //-- Level of messages output by the solver GLPK_GET_INT_PARAM (PARAM, "msglev", glpIntParam[0]); if (glpIntParam[0] < 0 || glpIntParam[0] > 3) { mexErrMsgTxt("glpkcc: param.msglev must be 0 (no output [default]) or 1 (error messages only) or 2 (normal output) or 3 (full output)"); } //-- scaling option GLPK_GET_INT_PARAM (PARAM, "scale", glpIntParam[1]); if (glpIntParam[1] < 0 || glpIntParam[1] > 2) { mexErrMsgTxt("glpkcc: param.scale must be 0 (no scaling) or 1 (equilibration scaling [default]) or 2 (geometric mean scaling)"); } //-- Dual dimplex option GLPK_GET_INT_PARAM (PARAM, "dual", glpIntParam[2]); if (glpIntParam[2] < 0 || glpIntParam[2] > 1) { mexErrMsgTxt("glpkcc: param.dual must be 0 (do NOT use dual simplex [default]) or 1 (use dual simplex)"); } //-- Pricing option GLPK_GET_INT_PARAM (PARAM, "price", glpIntParam[3]); if (glpIntParam[3] < 0 || glpIntParam[3] > 1) { mexErrMsgTxt("glpkcc: param.price must be 0 (textbook pricing) or 1 (steepest edge pricing [default])"); } //-- Solution rounding option GLPK_GET_INT_PARAM (PARAM, "round", glpIntParam[4]); if (glpIntParam[4] < 0 || glpIntParam[4] > 1) { mexErrMsgTxt("glpkcc: param.round must be 0 (report all primal and dual values [default]) or 1 (replace tiny primal and dual values by exact zero)"); } //-- Simplex iterations limit GLPK_GET_INT_PARAM (PARAM, "itlim", glpIntParam[5]); //-- Simplex iterations count GLPK_GET_INT_PARAM (PARAM, "itcnt", glpIntParam[6]); //-- Output frequency, in iterations GLPK_GET_INT_PARAM (PARAM, "outfrq", glpIntParam[7]); //-- Branching heuristic option GLPK_GET_INT_PARAM (PARAM, "branch", glpIntParam[14]); if (glpIntParam[14] < 0 || glpIntParam[14] > 2) { mexErrMsgTxt("glpkcc: param.branch must be (MIP only) 0 (branch on first variable) or 1 (branch on last variable) or 2 (branch using a heuristic by Driebeck and Tomlin [default]"); } //-- Backtracking heuristic option GLPK_GET_INT_PARAM (PARAM, "btrack", glpIntParam[15]); if (glpIntParam[15] < 0 || glpIntParam[15] > 2) { mexErrMsgTxt("glpkcc: param.btrack must be (MIP only) 0 (depth first search) or 1 (breadth first search) or 2 (backtrack using the best projection heuristic [default]"); } //-- Presolver option GLPK_GET_INT_PARAM (PARAM, "presol", glpIntParam[16]); if (glpIntParam[16] < 0 || glpIntParam[16] > 1) { mexErrMsgTxt("glpkcc: param.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])"); } //-- Generating cuts GLPK_GET_INT_PARAM (PARAM, "usecuts", glpIntParam[17]); if (glpIntParam[17] < 0 || glpIntParam[17] > 1) { mexErrMsgTxt("glpkcc: param.usecuts must be 0 (do NOT generate cuts) or 1 (generate Gomory's cuts [default])"); } //-- LPsolver option int lpsolver = 1; GLPK_GET_INT_PARAM (PARAM, "lpsolver", lpsolver); if (lpsolver < 1 || lpsolver > 2) { mexErrMsgTxt("glpkcc: param.lpsolver must be 1 (simplex method) or 2 (interior point method)"); } //-- Save option int save_pb = 0; char *save_filename = NULL; char *filetype = NULL; GLPK_GET_INT_PARAM (PARAM, "save", save_pb); save_pb = (save_pb != 0); if (save_pb){ // -- Look for the name -- mxArray *mxtmp=mxGetField(PARAM,0,"savefilename"); if ( mxtmp != NULL ){ int nl=mxGetNumberOfElements(mxtmp)+1; nl=nl+4; // increase size to consider then extension .xxx save_filename=(char *)mxCalloc(nl,sizeof(char)); if (mxGetString(mxtmp, save_filename, nl) != 0) mexErrMsgTxt("glpkcc: Could not load file name to save."); }else{ // Default file name save_filename= (char *)mxCalloc(9, sizeof(char)); strcpy(save_filename,"outpb"); } // -- Look for the type -- char save_filetype[4]; mxArray *txtmp=mxGetField(PARAM,0,"savefiletype"); if ( txtmp != NULL ){ int nl=mxGetNumberOfElements(txtmp)+1; filetype=(char *)mxCalloc(nl,sizeof(char)); if (mxGetString(txtmp, filetype, nl) != 0) mexErrMsgTxt("glpkcc: Could not load file type."); if (!strcmp(filetype,"fixedmps") || !strcmp(filetype,"freemps")){ strcpy(save_filetype,".mps"); } else { if (!strcmp(filetype,"cplex")) strcpy(save_filetype,".lp"); else { if (!strcmp(filetype,"plain")) strcpy(save_filetype,".txt"); } } }else{ filetype= (char *)mxCalloc(5, sizeof(char)); strcpy(filetype,"cplex"); strcpy(save_filetype,".lp"); // Default file type } strcat(save_filename,save_filetype); // name.extension } // MPS parameters //-- mpsinfo GLPK_GET_INT_PARAM (PARAM, "mpsinfo", glpIntParam[8]); //-- mpsobj GLPK_GET_INT_PARAM (PARAM, "mpsobj", glpIntParam[9]); if (glpIntParam[9] < 0 || glpIntParam[9] > 2) { mexErrMsgTxt("glpkcc: param.mpsobj must be 0 (never output objective function row) or 1 (always output objective function row ) or 2 [default](output objective function row if the problem has no free rows)"); } //-- mpsorig GLPK_GET_INT_PARAM (PARAM, "mpsorig", glpIntParam[10]); //-- mpswide GLPK_GET_INT_PARAM (PARAM, "mpswide", glpIntParam[11]); //-- mpsfree GLPK_GET_INT_PARAM (PARAM, "mpsfree", glpIntParam[12]); //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //-- Real parameters //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //-- Ratio test option GLPK_GET_REAL_PARAM (PARAM, "relax", 0); //-- Relative tolerance used to check if the current basic solution //-- is primal feasible GLPK_GET_REAL_PARAM (PARAM, "tolbnd", 1); //-- Absolute tolerance used to check if the current basic solution //-- is dual feasible GLPK_GET_REAL_PARAM (PARAM, "toldj", 2); //-- Relative tolerance used to choose eligible pivotal elements of //-- the simplex table in the ratio test GLPK_GET_REAL_PARAM (PARAM, "tolpiv", 3); GLPK_GET_REAL_PARAM (PARAM, "objll", 4); GLPK_GET_REAL_PARAM (PARAM, "objul", 5); GLPK_GET_REAL_PARAM (PARAM, "tmlim", 6); GLPK_GET_REAL_PARAM (PARAM, "outdly", 7); GLPK_GET_REAL_PARAM (PARAM, "tolint", 8); GLPK_GET_REAL_PARAM (PARAM, "tolobj", 9); //-- Assign pointers to the output parameters const char **extranames=(const char **)mxCalloc(4,sizeof(*extranames)); extranames[0]="lambda"; extranames[1]="redcosts"; extranames[2]="time"; extranames[3]="memory"; XMIN_OUT = mxCreateDoubleMatrix(mrowsc, 1, mxREAL); FMIN_OUT = mxCreateDoubleMatrix(1, 1, mxREAL); STATUS_OUT = mxCreateDoubleMatrix(1, 1, mxREAL); double *xmin = mxGetPr(XMIN_OUT); double *fmin = mxGetPr(FMIN_OUT); double *status = mxGetPr(STATUS_OUT); EXTRA_OUT = mxCreateStructMatrix(1, 1, 4, extranames); mxArray *mxlambda = mxCreateDoubleMatrix(mrowsA, 1, mxREAL); mxArray *mxredcosts = mxCreateDoubleMatrix(mrowsc, 1, mxREAL); mxArray *mxtime = mxCreateDoubleMatrix(1, 1, mxREAL); mxArray *mxmem = mxCreateDoubleMatrix(1, 1, mxREAL); double *lambda = mxGetPr(mxlambda); double *redcosts= mxGetPr(mxredcosts); double *time = mxGetPr(mxtime); double *mem = mxGetPr(mxmem); int jmpret = setjmp (mark); if (jmpret == 0) glpk (sense, mrowsc, mrowsA, c, nz, rn, cn, a, b, ctype, freeLB, lb, freeUB, ub, vartype, isMIP, lpsolver, save_pb, save_filename, filetype, xmin, fmin, status, lambda, redcosts, time, mem); if (! isMIP) { mxSetField(EXTRA_OUT,0,extranames[0],mxlambda); mxSetField(EXTRA_OUT,0,extranames[1],mxredcosts); } mxSetField(EXTRA_OUT,0,extranames[2],mxtime); mxSetField(EXTRA_OUT,0,extranames[3],mxmem); mxFree(rn); mxFree(cn); mxFree(a); mxFree(freeLB); mxFree(freeUB); mxFree(ctype); mxFree(vartype); mxFree(vtype); mxFree(extranames); mxFree(save_filename); mxFree(filetype); return; }