/******************************************************** * Xpress-BCL Java Example Problems * ================================ * * file xbdelvr.java * ````````````````` * Transportation problem. * * (c) 2008-2024 Fair Isaac Corporation * author: S.Heipcke, Jan. 2000, rev. Mar. 2011 ********************************************************/ import com.dashoptimization.*; import java.io.*; public class xbdelvr { static final int NSupp = 10; /* Number of suppliers */ static final int NCust = 7; /* Number of customers */ static final int MaxArcs = 100; /* Max. num. of non-zero cost values */ static final String VANFILE = System.getProperty("XPRBDATA") + "/delivery/ifvan.dat"; static final String COSTFILE = System.getProperty("XPRBDATA") + "/delivery/cost.dat"; /****DATA****/ /* Supplier: London Luton B'ham Bristl Derby Stckpt */ static final double SUPPLY[] = { 140.0, 600.0, 50.0, 10.0, 400.0, 200.0, /* Supplier: York Derby Soton Scnthp */ 20.0, 90.0, 30.0, 12 }; /* Customer: London Livpol Doncst York Hull Manchr */ static final double DEMAND[] = { 123.3, 56.4, 17.1, 192.8, 310.0, 47.0, /* Customer: Shffld */ 86 }; static double[][] COST; /* Cost per supplier-customer pair */ static double[][] IFVAN; /* Non-zero if route uses vans instead of lorries */ static final double VANCAP = 40; /* Capacity on routes that use vans */ /***********************************************************************/ static void modDelivery() throws IOException { try (XPRBprob p = new XPRBprob("Delivery"); /* Initialize BCL and create a new problem */ XPRBexprContext context = new XPRBexprContext() /* Release XPRBexpr instances at end of block. */) { XPRBexpr lobj, lc; int s, c; XPRBvar[][] x; /****VARIABLES****/ x = new XPRBvar[NSupp][NCust]; for (s = 0; s < NSupp; s++) for (c = 0; c < NCust; c++) x[s][c] = p.newVar("x_s" + s); /****OBJECTIVE****/ lobj = new XPRBexpr(); for (s = 0; s < NSupp; s++) /* Objective: Minimize total cost */ for (c = 0; c < NCust; c++) lobj.add(x[s][c].mul(COST[s][c])); p.setObj(lobj); /* Set objective function */ /****CONSTRAINTS****/ for (c = 0; c < NCust; c++) { /* Satisfy demand of each customer */ lc = new XPRBexpr(); for (s = 0; s < NSupp; s++) lc.add(x[s][c]); p.newCtr("Demand", lc.gEql(DEMAND[c])); } for (s = 0; s < NSupp; s++) { /* Keep within supply at each supplier*/ lc = new XPRBexpr(); for (c = 0; c < NCust; c++) lc.add(x[s][c]); p.newCtr("Supply", lc.lEql(SUPPLY[s])); } /****BOUNDS****/ for (s = 0; s < NSupp; s++) for (c = 0; c < NCust; c++) if (IFVAN[s][c] != 0) x[s][c].setUB(VANCAP); /****SOLVING + OUTPUT****/ p.exportProb(XPRB.MPS, "delivery"); /* Write out an MPS file */ p.setSense(XPRB.MINIM); /* Set objective sense to minimization */ p.lpOptimize(""); /* Solve the LP-problem */ System.out.println("Objective: " + p.getObjVal()); /* Get objective value */ for (s = 0; s < NSupp; s++) /* Print out the solution values */ for (c = 0; c < NCust; c++) System.out.print(x[s][c].getName() + ":" + x[s][c].getSol() + " "); System.out.println(); } } /***********************************************************************/ /**** Initialize the stream tokenizer ****/ static StreamTokenizer initST(FileReader file) { StreamTokenizer st = null; st = new StreamTokenizer(file); /* Initialize the stream tokenizer */ st.commentChar('!'); /* Use the character '!' for comments */ st.eolIsSignificant(true); /* Return end-of-line character */ st.ordinaryChar(','); /* Use ',' as separator */ st.parseNumbers(); /* Read numbers as numbers (not strings)*/ return st; } /**** Read multi line data file ****/ static void readMultiLineFile(String filename, double[][] data) throws IOException { FileReader datafile = null; StreamTokenizer st; int i = 0, j = 0; datafile = new FileReader(filename); st = initST(datafile); do { do { st.nextToken(); } while (st.ttype == st.TT_EOL); /* Skip empty lines */ while (st.ttype == st.TT_NUMBER) { data[j][i++] = st.nval; if (st.nextToken() != ',') { j++; i = 0; break; } st.nextToken(); } } while (st.ttype == st.TT_EOL); datafile.close(); } /**** Read data from files ****/ static void readData() throws IOException { int s, c; COST = new double[NSupp][NCust]; IFVAN = new double[NSupp][NCust]; /* Initialize data tables to 0: in the van data file some entries that are * zero are simply left out (that is, the lines are incomplete) */ for (s = 0; s < NSupp; s++) for (c = 0; c < NCust; c++) { COST[s][c] = 0; IFVAN[s][c] = 0; } /* Read the demand data file */ readMultiLineFile(COSTFILE, COST); /* Read the van data file */ readMultiLineFile(VANFILE, IFVAN); } /***********************************************************************/ public static void main(String[] args) { try { readData(); /* Data input from file */ modDelivery(); /* Problem formulation and solution */ } catch (IOException e) { System.err.println(e.getMessage()); System.exit(1); } } }