Apply an integer fixing heuristic to a MIP problem
|
|
|
| Type: | Power generation |
| Rating: | 3 (intermediate) |
| 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. |
| File(s): | RoundInt.java |
| Data file(s): | hpw15.mps |
|
|
|
| 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-2025 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.getSolution();
// 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.getSolution();
// 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);
}
}
}
|
© 2001-2025 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.
