The following Java code reads a Problem from an LP or MPS file and solves it. Commandline arguments are provided to choose solver and output options.
import qs.*; import java.io.*; /** * use as java simplesolver [params] prob_file * for paremeters see usage routine * needs qsopt.jar on classpath * * @author Monika Mevenkamp, All Rights Reserved */ class simplesolver { // the LP or MPS format file defining a problem private String fname; // the file format is LP (default) private boolean isLpFile; // use primal simplex algorithm to solve problem (default) private boolean solvePrimal; // print variable values (default optimal val only) private boolean printX; // print a complete solution report private boolean printReport; // turn on simplex tracing (default false) private boolean traceSimplex; // pricing strategy DANTZIG is default; private int price; private int DANTZIG = 0; private int STEEP = 1; private int DEVEX = 2; public simplesolver() { fname = null; isLpFile = true; solvePrimal = true; printX = false; price = DANTZIG; traceSimplex = false; } public simplesolver(String av[]) throws QSException { this(); getargs(av); } public int solveProblem() throws QSException, IOException { int status = QS.LP_UNSOLVED; Problem prob = Problem.read(fname, !isLpFile); if (prob == null) { throw new QSException("Could not parse problem."); } if (traceSimplex) // trace simplex actions prob.setparam(QS.PARAM_SIMPLEX_DISPLAY, 1); if (solvePrimal) { if (price == DANTZIG) { prob.setparam(QS.PARAM_PRIMAL_PRICING_I, QS.PRIMAL_DANTZIG); } else { if (price == DEVEX) { prob.setparam(QS.PARAM_PRIMAL_PRICING_I, QS.PRIMAL_DEVEX); } else { prob.setparam(QS.PARAM_PRIMAL_PRICING_I, QS.PRIMAL_STEEP); } } prob.setparam(QS.PARAM_PRIMAL_PRICING_II, prob.getparam(QS.PARAM_PRIMAL_PRICING_I)); prob.opt_primal(); } else { // solve dual if (price == DANTZIG) { prob.setparam(QS.PARAM_DUAL_PRICING_I, QS.PRIMAL_DANTZIG); } else { if (price == DEVEX) { prob.setparam(QS.PARAM_DUAL_PRICING_I, QS.PRIMAL_DEVEX); } else { prob.setparam(QS.PARAM_DUAL_PRICING_I, QS.PRIMAL_STEEP); } } prob.setparam(QS.PARAM_DUAL_PRICING_II, prob.getparam(QS.PARAM_DUAL_PRICING_I)); prob.opt_dual(); } status = prob.get_status(); if (status == QS.LP_OPTIMAL) { System.out.println("Optimal\n\t" + prob.get_objname() + " = " + prob.get_objval()); if (printX) { System.out.println("\nVariable Values (non zero only):"); prob.print_x(new Reporter(System.out), true, 6); } if (printReport) { int nrows = prob.get_rowcount(); double pi[] = new double[nrows]; double slack[] = new double[nrows]; String rows[] = new String[nrows]; int ncols = prob.get_colcount(); double x[] = new double[ncols]; double rc[] = new double[ncols]; String cols[] = new String[ncols]; prob.get_rownames(rows); prob.get_colnames(cols); prob.get_solution(x, pi, slack, rc); System.out.println("Row information"); for (int i = 0; i < nrows; i++) { if ((pi[i] != 0.0) || (slack[i] != 0.0)) { System.out.println("\t" + rows[i] + ": pi = " + pi[i] + "; " + "slack = " + slack[i]); } } System.out.println("Column information"); for (int j = 0; j < ncols; j++) { if (x[j] != 0.0 || rc[j] != 0.0) { System.out.println("\t" + cols[j] + ": x = " + x[j] + "; " + "rc = " + rc[j]); } } } } return status; } public static void main(String av[]) { simplesolver solver = null; try { solver = new simplesolver(av); System.out.println("SOLVER: " + solver); if (solver.solveProblem() == QS.LP_OPTIMAL) { System.out.println("SUCCESS!\n"); } else { System.out.println("Problem maybe unbounded or infeasible.\n"); } } catch (QSException e) { System.err.println(e.toString()); } catch (IOException e) { System.err.println("Could not read file \"" + solver.fname + "\".\n"); System.err.println(e); } } public static void usage() throws QSException { String msg; msg = "Usage: java simplesolver [- below -] prob_file\n"; msg += " -M input file is in MPS format " + "(default: LP format)\n"; msg += " -d use dual simplex " + "(default: primal simplex)\n"; msg += " -X print variable values " + "(default optimal value only)\n"; msg += " -R print a solution report " + "(default no report)\n"; msg += " -T trace simplex progress " + "(default no traces)\n"; msg += " -a use DANTZIG pricing\n"; msg += " -s use STEEP pricing in simplex " + "(default DANTZIG)\n"; msg += " -x use DEVEX pricing in simplex " + "(default DANTZIG)\n"; msg += "\n"; msg += " prob_file contains the lp definition"; throw new QSException(msg); } public void getargs(String av[]) throws QSException { try { int i = 0; while (av[i].charAt(0) == '-') { switch (av[i].charAt(1)) { case 'M' : isLpFile = false; break; case 'R' : printReport = true; break; case 'X' : printX = true; break; case 'd' : solvePrimal = false; break; case 'T' : traceSimplex = true; break; case 'a' : price = DANTZIG; break; case 's' : price = STEEP; break; case 'x' : price = DEVEX; break; default : usage(); } i++; } fname = av[i]; if (fname == null) { usage(); } } catch (ArrayIndexOutOfBoundsException e) { usage(); } } public String toString() { String s = "File \"" + fname + "\""; if (!isLpFile) s += " MPS format;"; if (!solvePrimal) s += " opt_dual;"; if (!printX) s += " print var values; "; if (!printReport) s += " print sol report; "; if (price == DANTZIG) s += " DANTZIG;"; if (price == DEVEX) s += " DEVEX;"; if (price == STEEP) s += " STEEP;"; return s; } }