/***************************************************************************************\
* Name:        MipSolEnum.java                                   Fair Isaac 13/06/2008 *
* Purpose:     10 best solutions with the MIP solution enumerator                      *
* 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 *
*              run the MIP solution enumerator on the problem using the default setup  *
*              obtaining the best 10 solutions. The best 10 solutions are stored to a  *
*              MIP solution pool.  The solutions' objectives and solution values are   *
*              printed to screen.                                                      *
* Input:       hpw15.mps                                                               *
\***************************************************************************************/

import java.io.*;
import com.dashoptimization.*;

public class MipSolEnum {
    public static void main(String[] args) throws Exception {
        String model = args.length == 0 ? "../data/hpw15" : args[0];
        try (XPRSprob prob = new XPRSprob(null);
             XPRSmipsolpool msp = new XPRSmipsolpool();
             XPRSmipsolenum mse = new XPRSmipsolenum())
        {
            prob.addMsgHandlerListener(System.out);
            prob.readProb(model);
            int nCols = prob.attributes().getCols();

            /* Avoid duplicated solutions from heuristics. */
            msp.controls().setDuplicateSolutionsPolicy(3);

            /* Disable dual reductions to prevent dominated solutions from being */
            /* presolved away. */
            prob.controls().setMIPDualReductions(2);

            /* Run the enumeration */
            IntHolder nMaxSols = new IntHolder(10);
            mse.minim(prob,msp,new XPRSdefaultMipSolEnumHandler(), null, nMaxSols);

            /* Print out the solutions found */
            int nSols = mse.attributes().getSolutions();
            for (int i=1;i<=nSols;i++) {
                int[] iSolutionId = new int[1];
                DoubleHolder dObj = new DoubleHolder();
                mse.getSolList(XPRS.MSE_METRIC_MIPOBJECT,i,i,iSolutionId,null,null);
                mse.getSolMetric(iSolutionId[0], null, XPRS.MSE_METRIC_MIPOBJECT, dObj);
                System.out.println("--------\n" + i + " = " + dObj.value);
                for (int j=0;j<nCols;j++) {
                    double[] dSol = new double[1];
                    msp.getSol(iSolutionId[0],null,dSol,j,j,null);
                    System.out.println(j + " = " + dSol[0]);
                }
            }

        }
    }
}
