| |||||||||||
Apply an integer fixing heuristic to a MIP problem Description We take the power generation problem stored in hpw15.mps which seeks to optimise the operating pattern of a group of electricity generators. We solve this MIP with a very loose integer tolerance and then fix all binary and integer variables to their rounded integer values, changing both their lower and upper bounds. We then solve the resulting LP. The results are displayed on screen and the problem statistics stored in a logfile.
Source Files By clicking on a file name, a preview is opened at the bottom of this page.
Data Files RoundInt.java /*********************************************************************** Xpress Optimizer Examples ========================= file RoundInt.java ``````````````` Apply an integer fixing heuristic to a MIP problem. The program also demonstrates the use of the integer solution callback. (c) 2021-2024 Fair Isaac Corporation ***********************************************************************/ import com.dashoptimization.DefaultMessageListener; import com.dashoptimization.XPRS; import com.dashoptimization.XPRSintSolListener; import com.dashoptimization.XPRSprob; import static com.dashoptimization.XPRSenumerations.CutStrategy; /** Apply an integer fixing heuristic to a MIP problem. * * The program also demonstrates the use of the integer solution callback. * * We take the power generation problem stored in hpw15.mps which * seeks to optimise the operating pattern of a group of electricity * generators. We solve this MIP with a very loose integer tolerance * and then fix all binary and integer variables to their rounded * integer values, changing both their lower and upper bounds. We then * solve the resulting LP. * * The results are displayed on screen and the problem statistics * stored in a logfile. */ public class RoundInt { /** The very loose integrality tolerance we use in the example. */ public static final double TOL = 0.3; /** Run the example. * @param args The problem name. This is optional. If no problem name * is specified then "hpw15" is used. */ public static void main(String[] args) { String problem = args.length == 0 ? "../data/hpw15" : args[0]; if (args.length > 0) problem = args[0]; String logFile = "RountInt.log"; try (XPRSprob prob = new XPRSprob(null)) { // Delete and define log file new java.io.File(logFile).delete(); prob.setLogFile(logFile); // Install default output: We only print warning and error messages. prob.addMessageListener(new DefaultMessageListener(null, System.err, System.err)); // Read the problem file prob.readProb(problem); // Disable cuts - or the optimal solution will be found at the top // node and the integer solution callback will hardly be used. prob.controls().setCutStrategy(CutStrategy.NONE); // Solve MIP with loose integer tolerance // Set integer feasibility tolerance prob.controls().setMIPTol(TOL); // Tell Optimizer to print out MIP information at each node and // call IntSol whenever an integer solution is found prob.controls().setMIPLog(3); prob.addIntSolListener(new IntSol()); // Get the number of columns int cols = prob.attributes().getCols(); // Solve the MIP problem and get the solution values System.out.printf("Applying an integer fixing heuristic to problem %s:-%n%n", problem); System.out.printf("Solving MIP:%n%n"); prob.mipOptimize(); double[] x = prob.getMipSolX(); // Round off the values of all binary and integer variables XPRSprob.MIPEntityInfo info = prob.getDiscreteCols(); int mipents = info.coltype.length; int[] glInd = info.colind; byte[] glType = info.coltype; // Allocate memory for bound arrays int[] bndInd = new int[mipents]; double[] bndVal = new double[mipents]; byte[] bndType = new byte[mipents]; // Initialise bound counter int nBnd = 0; // Go through MIP entities for (int k = 0; k < mipents; ++k) { // Test whether each is a binary or integer variable if (glType[k] == 'B' || glType[k] == 'I') { // Hold the index of the variable int j = glInd[k]; // Store the index, round the variable's value to the // nearest integer, and reset both its upper and lower // bounds bndInd[nBnd] = j; bndVal[nBnd] = Math.round(x[j]); bndType[nBnd] = 'B'; ++nBnd; } } // Instruct Optimizer to change the bounds prob.chgBounds(nBnd, bndInd, bndType, bndVal); System.out.printf("\nAfter MIP search, %d binary and integer variables were fixed%n%n", nBnd); // Solve the resulting LP // Solve the LP and get the solution values prob.lpOptimize(); double[] y = prob.getLpSolX(); // Get and print the LP objective function value System.out.printf("After solving the LP the final objective value was %g%n%n", prob.attributes().getLPObjVal()); // Print the non-zero MIP and corresponding LP solution values for // comparison: System.out.printf("The non-zero MIP and LP solution values are:%n%n"); for (int j = 0; j < cols; ++j) { if (x[j] != 0.0) { System.out.printf(" x[%2d] = %5.1f %5.3g%n", j, x[j], y[j]); } } System.out.println(); } } /** Callback to display objective value associated with a node. */ private static final class IntSol implements XPRSintSolListener { /** Displays the objective value associated with a node in the MIP * search. * This function is called every time an integer solution has been * found. * @param prob The problem for which a solution was found. * @param vContext unused. */ @Override public void XPRSintSolEvent(XPRSprob prob, Object vContext) { // Get the node number int node = prob.attributes().getCurrentNode(); // Get the objective function value double obj = prob.attributes().getLPObjVal(); System.out.printf(" Node %d (Objective value = %g)%n", node, obj); } } } | |||||||||||
© Copyright 2024 Fair Isaac Corporation. |