int CClp_create(CClp *lp, const char *name) { /* CREATES an empty lp. This supports an alternative to CClp_loadlp for loading a problem. - name attaches a name to the LP (it can be used by the LP solver in io routines). */ insist(lp->lp == NULL); lp->lp = lpx_create_prob(); lpx_set_prob_name(lp->lp, (char *)name); return 0; }
int main(void) { LPX *lp; int ia[1+1000], ja[1+1000]; double ar[1+1000], Z, x1, x2, x3; s1: lp = lpx_create_prob(); s2: lpx_set_prob_name(lp, "sample"); s3: lpx_set_obj_dir(lp, LPX_MAX); s4: lpx_add_rows(lp, 3); s5: lpx_set_row_name(lp, 1, "p"); s6: lpx_set_row_bnds(lp, 1, LPX_UP, 0.0, 100.0); s7: lpx_set_row_name(lp, 2, "q"); s8: lpx_set_row_bnds(lp, 2, LPX_UP, 0.0, 600.0); s9: lpx_set_row_name(lp, 3, "r"); s10: lpx_set_row_bnds(lp, 3, LPX_UP, 0.0, 300.0); s11: lpx_add_cols(lp, 3); s12: lpx_set_col_name(lp, 1, "x1"); s13: lpx_set_col_bnds(lp, 1, LPX_LO, 0.0, 0.0); s14: lpx_set_obj_coef(lp, 1, 10.0); s15: lpx_set_col_name(lp, 2, "x2"); s16: lpx_set_col_bnds(lp, 2, LPX_LO, 0.0, 0.0); s17: lpx_set_obj_coef(lp, 2, 6.0); s18: lpx_set_col_name(lp, 3, "x3"); s19: lpx_set_col_bnds(lp, 3, LPX_LO, 0.0, 0.0); s20: lpx_set_obj_coef(lp, 3, 4.0); s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ s30: lpx_load_matrix(lp, 9, ia, ja, ar); s31: lpx_simplex(lp); s32: Z = lpx_get_obj_val(lp); s33: x1 = lpx_get_col_prim(lp, 1); s34: x2 = lpx_get_col_prim(lp, 2); s35: x3 = lpx_get_col_prim(lp, 3); s36: printf("\nZ = %g; x1 = %g; x2 = %g; x3 = %g\n", Z, x1, x2, x3); s37: lpx_delete_prob(lp); return 0; }
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; }
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_loadlp(CClp *lp, const char *name, int ncols, int nrows, int objsense, double *obj, double *rhs, char *sense, int *matbeg, int *matcnt, int *matind, double *matval, double *lb, double *ub) { /* LOADS the data into the LP. - name attaches a name to the LP (it can be used by the LP solver in io routines) - ncols and nrows give the number of columns and rows in the LP - objsense should be 1 for minimize and -1 for maximize - obj and rhs are arrays giving the objective function and rhs - sense is an array specifying 'L', 'E', or 'G' for each of the rows - matbeg, matcnt, matind, and matval give the coefficients of the constraint matrix in column by column order. matbeg gives the index of the start of each column; matcnt gives the number of coefficients in each column; matind gives the indices of the rows where the coefficients are located in the constraint matrix (so for column j, the indices are given in matcnt[j] locations starting at matind[matbeg[j]]; and matval gives the actual coefficients (organized like matind). - lb and ub are arrays giving the upper and lower bounds of the variables. */ int i, j; /* create empty problem object */ insist(lp->lp == NULL); lp->lp = lpx_create_prob(); lpx_set_prob_name(lp->lp, (char *)name); /* set objective sense */ switch (objsense) { case +1: /* minimization */ lpx_set_obj_dir(lp->lp, LPX_MIN); break; case -1: /* maximization */ lpx_set_obj_dir(lp->lp, LPX_MAX); break; default: insist(objsense != objsense); } /* add rows */ lpx_add_rows(lp->lp, nrows); for (i = 0; i < nrows; i++) { int seqn, type; double lo, up; seqn = 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); } /* add columns and constraint coefficients */ lpx_add_cols(lp->lp, ncols); for (j = 0; j < ncols; j++) { int seqn, type, k; double lo, up; seqn = j+1; lpx_set_col_coef(lp->lp, seqn, obj == NULL ? 0.0 : obj[j]); lo = lb[j], up = ub[j]; /* check for finite bounds */ insist(-1e12 <= lo && lo <= up && up <= +1e12); type = (lo == up ? LPX_FX : LPX_DB); lpx_set_col_bnds(lp->lp, seqn, type, lo, up); for (k = matbeg[j]; k < matbeg[j] + matcnt[j]; k++) matind[k]++; lpx_set_mat_col(lp->lp, seqn, matcnt[j], &matind[matbeg[j]] - 1, &matval[matbeg[j]] - 1); for (k = matbeg[j]; k < matbeg[j] + matcnt[j]; k++) matind[k]--; } return 0; }
LPX *lpx_extract_prob(void *_mpl) { MPL *mpl = _mpl; LPX *lp; int m, n, i, j, t, kind, type, len, *ind; double lb, ub, *val; /* create problem instance */ lp = lpx_create_prob(); /* set problem name */ lpx_set_prob_name(lp, mpl_get_prob_name(mpl)); /* build rows (constraints) */ m = mpl_get_num_rows(mpl); if (m > 0) lpx_add_rows(lp, m); for (i = 1; i <= m; i++) { /* set row name */ lpx_set_row_name(lp, i, mpl_get_row_name(mpl, i)); /* set row bounds */ type = mpl_get_row_bnds(mpl, i, &lb, &ub); switch (type) { case MPL_FR: type = LPX_FR; break; case MPL_LO: type = LPX_LO; break; case MPL_UP: type = LPX_UP; break; case MPL_DB: type = LPX_DB; break; case MPL_FX: type = LPX_FX; break; default: insist(type != type); } if (type == LPX_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb))) { type = LPX_FX; if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub; } lpx_set_row_bnds(lp, i, type, lb, ub); /* warn about non-zero constant term */ if (mpl_get_row_c0(mpl, i) != 0.0) print("lpx_read_model: row %s; constant term %.12g ignored", mpl_get_row_name(mpl, i), mpl_get_row_c0(mpl, i)); } /* build columns (variables) */ n = mpl_get_num_cols(mpl); if (n > 0) lpx_add_cols(lp, n); for (j = 1; j <= n; j++) { /* set column name */ lpx_set_col_name(lp, j, mpl_get_col_name(mpl, j)); /* set column kind */ kind = mpl_get_col_kind(mpl, j); switch (kind) { case MPL_NUM: break; case MPL_INT: case MPL_BIN: lpx_set_class(lp, LPX_MIP); lpx_set_col_kind(lp, j, LPX_IV); break; default: insist(kind != kind); } /* set column bounds */ type = mpl_get_col_bnds(mpl, j, &lb, &ub); switch (type) { case MPL_FR: type = LPX_FR; break; case MPL_LO: type = LPX_LO; break; case MPL_UP: type = LPX_UP; break; case MPL_DB: type = LPX_DB; break; case MPL_FX: type = LPX_FX; break; default: insist(type != type); } if (kind == MPL_BIN) { if (type == LPX_FR || type == LPX_UP || lb < 0.0) lb = 0.0; if (type == LPX_FR || type == LPX_LO || ub > 1.0) ub = 1.0; type = LPX_DB; } if (type == LPX_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb))) { type = LPX_FX; if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub; } lpx_set_col_bnds(lp, j, type, lb, ub); } /* load the constraint matrix */ ind = ucalloc(1+n, sizeof(int)); val = ucalloc(1+n, sizeof(double)); for (i = 1; i <= m; i++) { len = mpl_get_mat_row(mpl, i, ind, val); lpx_set_mat_row(lp, i, len, ind, val); } /* build objective function (the first objective is used) */ for (i = 1; i <= m; i++) { kind = mpl_get_row_kind(mpl, i); if (kind == MPL_MIN || kind == MPL_MAX) { /* set objective name */ lpx_set_obj_name(lp, mpl_get_row_name(mpl, i)); /* set optimization direction */ lpx_set_obj_dir(lp, kind == MPL_MIN ? LPX_MIN : LPX_MAX); /* set constant term */ lpx_set_obj_coef(lp, 0, mpl_get_row_c0(mpl, i)); /* set objective coefficients */ len = mpl_get_mat_row(mpl, i, ind, val); for (t = 1; t <= len; t++) lpx_set_obj_coef(lp, ind[t], val[t]); break; } } /* free working arrays */ ufree(ind); ufree(val); /* bring the problem object to the calling program */ return lp; }
int TankBlendOptimiser::go() { lp = lpx_create_prob(); lpx_set_int_parm(lp, LPX_K_MSGLEV, 0); // 0 = no output lpx_set_int_parm(lp, LPX_K_SCALE, 3); // 3 = geometric mean scaling, then equilibration scaling lpx_set_int_parm(lp, LPX_K_DUAL, 1); // 1 = if initial basic solution is dual feasible, use the dual simplex lpx_set_int_parm(lp, LPX_K_ROUND, 1); // 1 = replace tiny primal and dual values by exact zero lpx_set_int_parm(lp, LPX_K_PRESOL, 1); // 1 = use the built-in presolver. lpx_set_prob_name(lp, "Blend Optimiser"); lpx_set_obj_dir(lp, LPX_MIN); // Columns... lpx_add_cols(lp, cols); for (int i=0; i<tanks; i++) // 0.0 < x < tankMax { if (tankMax[i]>0.0) lpx_set_col_bnds(lp, col, LPX_DB, 0.0, tankMax[i]); else lpx_set_col_bnds(lp, col, LPX_FX, 0.0, 0.0); col++; } for (int i=0; i<tanks; i++) // 0.0 < slackTankLow { lpx_set_col_bnds(lp, col, LPX_LO, 0.0, 0.0); lpx_set_obj_coef(lp, col, tankLowPenalty[i]); // penalty weight. col++; } for (int i=0; i<tanks; i++) // 0.0 < slackTankHigh { lpx_set_col_bnds(lp, col, LPX_LO, 0.0, 0.0); lpx_set_obj_coef(lp, col, tankHighPenalty[i]); // penalty weight. col++; } for (int i=0; i<assays; i++) // 0.0 < slackAssayLow { lpx_set_col_bnds(lp, col, LPX_LO, 0.0, 0.0); lpx_set_obj_coef(lp, col, assayLowPenalty[i]); // penalty weight. col++; } for (int i=0; i<assays; i++) // 0.0 < slackAssayHigh { lpx_set_col_bnds(lp, col, LPX_LO, 0.0, 0.0); lpx_set_obj_coef(lp, col, assayHighPenalty[i]); // penalty weight. col++; } for (int i=0; i<assays; i++) // 0.0 < slackAssayRatioLow for (int j=0; j<assays; j++) { lpx_set_col_bnds(lp, col, LPX_LO, 0.0, 0.0); lpx_set_obj_coef(lp, col, assayRatioLowPenalty[i][j]); // penalty weight. col++; } for (int i=0; i<assays; i++) // 0.0 < slackAssayRatioHigh for (int j=0; j<assays; j++) { lpx_set_col_bnds(lp, col, LPX_LO, 0.0, 0.0); lpx_set_obj_coef(lp, col, assayRatioHighPenalty[i][j]); // penalty weight. col++; } // Rows... lpx_add_rows(lp, rows); { // x1 + ... + xn = 1.0 lpx_set_row_bnds(lp, row, LPX_FX, 1.0, 1.0); for (int i=0; i<tanks; i++) ia[constraint] = row, ja[constraint] = 1+i, ar[constraint++] = 1.0; row++; } for (int i=0; i<tanks; i++) // tankLow < tank + slackTankLow { lpx_set_row_bnds(lp, row, LPX_LO, tankLow[i], 0.0); ia[constraint] = row, ja[constraint] = 1+i, ar[constraint++] = 1.0; ia[constraint] = row, ja[constraint] = 1+i+tanks, ar[constraint++] = 1.0; row++; } for (int i=0; i<tanks; i++) // tank - slackTankHigh < tankHigh { lpx_set_row_bnds(lp, row, LPX_UP, 0.0, tankHigh[i]); ia[constraint] = row, ja[constraint] = 1+i, ar[constraint++] = 1.0; ia[constraint] = row, ja[constraint] = 1+i+2*tanks, ar[constraint++] = -1.0; row++; } for (int i=0; i<assays; i++) // assayLow < assay + slackAssayLow { lpx_set_row_bnds(lp, row, LPX_LO, assayLow[i], 0.0); for (int j=0; j<tanks; j++) { if (assayConc[i][j]>0.0) ia[constraint] = row, ja[constraint] = 1+j, ar[constraint++] = assayConc[i][j]; } ia[constraint] = row, ja[constraint] = 1+i+3*tanks, ar[constraint++] = 1.0; row++; } for (int i=0; i<assays; i++) // assay - slackAssayHigh < assayHigh { lpx_set_row_bnds(lp, row, LPX_UP, 0.0, assayHigh[i]); for (int j=0; j<tanks; j++) { if (assayConc[i][j]>0.0) ia[constraint] = row, ja[constraint] = 1+j, ar[constraint++] = assayConc[i][j]; } ia[constraint] = row, ja[constraint] = 1+i+3*tanks+assays, ar[constraint++] = -1.0; row++; } for (int i=0; i<assays; i++) // 0 < assayNum - assayRatioLow*assayDen + slackAssayLow for (int j=0; j<assays; j++) { if (assayRatioLowEnabled[i][j]) lpx_set_row_bnds(lp, row, LPX_LO, 0.0, 0.0); else lpx_set_row_bnds(lp, row, LPX_FR, 0.0, 0.0); for (int k=0; k<tanks; k++) { if (assayConc[i][k] - assayRatioLow[i][j]*assayConc[j][k]!=0.0) ia[constraint] = row, ja[constraint] = 1+k, ar[constraint++] = assayConc[i][k] - assayRatioLow[i][j]*assayConc[j][k]; } ia[constraint] = row, ja[constraint] = 1+i*assays+j+3*tanks+2*assays, ar[constraint++] = 1.0; row++; } for (int i=0; i<assays; i++) // assayNum - assayRatioHigh*assayDen - slackAssayHigh < 0 for (int j=0; j<assays; j++) { if (assayRatioHighEnabled[i][j]) lpx_set_row_bnds(lp, row, LPX_UP, 0.0, 0.0); else lpx_set_row_bnds(lp, row, LPX_FR, 0.0, 0.0); for (int k=0; k<tanks; k++) { if (assayConc[i][k] - assayRatioHigh[i][j]*assayConc[j][k]!=0.0) ia[constraint] = row, ja[constraint] = 1+k, ar[constraint++] = assayConc[i][k] - assayRatioHigh[i][j]*assayConc[j][k]; } ia[constraint] = row, ja[constraint] = 1+i*assays+j+3*tanks+2*assays+assays*assays, ar[constraint++] = -1.0; row++; } lpx_load_matrix(lp, constraint-1, ia, ja, ar); int exitCode = lpx_simplex(lp); for (int i=0; i<tanks; i++) tank[i] = lpx_get_col_prim(lp, 1+i); for (int i=0; i<assays; i++) { assay[i] = 0.0; for (int j=0; j<tanks; j++) assay[i] += lpx_get_col_prim(lp, 1+j)*assayConc[i][j]; } return exitCode; // LPX_E_OK 200 /* success */ // LPX_E_FAULT 204 /* unable to start the search */ // LPX_E_ITLIM 207 /* iterations limit exhausted */ // LPX_E_TMLIM 208 /* time limit exhausted */ // LPX_E_SING 211 /* problems with basis matrix */ // LPX_E_NOPFS 213 /* no primal feas. sol. (LP presolver) */ // LPX_E_NODFS 214 /* no dual feas. sol. (LP presolver) */ // Usually: // LPX_E_OK = Solution found. // LPX_E_NOPFS = Sum-to-1.0 or tank-max constraints not met. // Others = Some major fault has occurred. }