FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

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.


roundint_java.zip[download all files]

Source Files
By clicking on a file name, a preview is opened at the bottom of this page.
RoundInt.java[download]

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);
        }
    }
}

Back to examples browserPrevious exampleNext example