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

Burglar - Use of index sets, formulating logical constraints

Description
Several versions of a simple knapsack problem:
  • xbburg: standard formlation
  • xbburgi: shows how to index an array of variables by an index set
  • xbburgl: adds several indicator constraints to state logical conditions
Further explanation of this example: Quick reference guide 'MIP formulations and linearizations', Section 4 Indicator constraints

xbburgjava.zip[download all files]

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





xbburgl.java

/********************************************************
 * Xpress-BCL Java Example Problems
 * ================================
 *
 * file xbburgl.java
 * `````````````````
 * Burglar problem.
 * Binary variable formulation with index sets.
 * -- Formulating logical conditions
 * with indicator constraints --
 *
 * (c) 2009-2024 Fair Isaac Corporation
 * author: S.Heipcke, June 2009, rev. Mar. 2011
 ********************************************************/

import com.dashoptimization.*;

public class xbburgl {
  /****DATA****/
  /* Item:                          ca  ne  va  pi  tv  vi  ch  br */
  static final double[] VALUE = {15, 100, 90, 60, 40, 15, 10, 1};

  /* Value of items */
  static final double[] WEIGHT = {2, 20, 20, 30, 40, 30, 60, 10};
  /* Weight of items */
  static final double WTMAX = 102; /* Max weight allowed for haul */

  static final String[] ITEMNAMES = {
    "camera", "necklace", "vase", "picture",
    "tv", "video", "chest", "brick"
  };

  static int NItems; /* Number of items */

  public static void main(String[] args) {
    try (XPRBprob p = new XPRBprob("BurglarL"); /* Initialize BCL and create a new problem */
        XPRBexprContext context =
            new XPRBexprContext() /* Release XPRBexpr instances at end of block. */) {
      XPRBvar[] x;
      XPRBindexSet ITEMS; /* Set of items */
      int i;
      XPRBexpr lobj, kn;
      XPRBctr Log3a, Log3b;

      /****INDICES****/
      ITEMS = p.newIndexSet("Items", ITEMNAMES.length); /* Create the index set */
      for (i = 0; i < ITEMNAMES.length; i++) ITEMS.addElement(ITEMNAMES[i]);

      NItems = ITEMS.getSize(); /* Get the size of the index set */

      /****VARIABLES****/
      x = new XPRBvar[NItems];
      for (i = 0; i < NItems; i++) x[i] = p.newVar("x_" + ITEMS.getIndexName(i), XPRB.BV);
      /* 1 if we take item i; 0 otherwise */

      /****OBJECTIVE****/
      lobj = new XPRBexpr();
      for (i = 0; i < NItems; i++) lobj.add(x[i].mul(VALUE[i]));
      p.setObj(lobj); /* Set objective: maximize total value */

      /****CONSTRAINTS****/
      kn = new XPRBexpr();
      for (i = 0; i < NItems; i++) kn.add(x[i].mul(WEIGHT[i]));
      p.newCtr("WtMax", kn.lEql(WTMAX)); /* Weight restriction */

      /**
       * Logic constraint: * Either take "vase" and "picture" or "tv" and "video" (but not both
       * pairs).
       */

      /* Values within each pair are the same */
      p.newCtr("Log1", x[ITEMS.getIndex("vase")].eql(x[ITEMS.getIndex("picture")]));
      /* x["vase"] == x["picture"] */
      p.newCtr("Log2", x[ITEMS.getIndex("tv")].eql(x[ITEMS.getIndex("video")]));
      /* x["tv"] == x["video"] */

      /* Choose exactly one pair */
      Log3a = p.newCtr("Log3a", x[ITEMS.getIndex("tv")].add(x[ITEMS.getIndex("video")]).lEql(0));
      /* x["tv"]+x["video"] <= 0 */
      Log3b = p.newCtr("Log3b", x[ITEMS.getIndex("tv")].add(x[ITEMS.getIndex("video")]).gEql(2));
      /* x["tv"]+x["video"] >= 2 */

      /* Turn the 2 constraints into indicator constraints */
      Log3a.setIndicator(1, x[ITEMS.getIndex("vase")]);
      /* x["vase"]=1 -> x["tv"]+x["video"]=0 */
      Log3b.setIndicator(-1, x[ITEMS.getIndex("vase")]);
      /* x["vase"]=0 -> x["tv"]+x["video"]=2 */

      /* Alternative MIP formulation (instead of Log3a and Log3b) */
      /*
        p.newCtr("Log3",
        x[ITEMS.getIndex("tv")].add(x[ITEMS.getIndex("vase")]).eql(1) );
      */
      /* x["tv"] = 1 - x["vase"] */

      /****SOLVING + OUTPUT****/
      p.setSense(XPRB.MAXIM); /* Choose the sense of the optimization */
      p.mipOptimize(""); /* Solve the MIP-problem */
      System.out.println("Objective: " + p.getObjVal()); /* Get objective value */

      for (i = 0; i < NItems; i++) /* Print out the chosen items */
        if (x[i].getSol() > 0) System.out.println(ITEMS.getIndexName(i) + ": " + x[i].getSol());
    }
  }
}

Back to examples browserPrevious exampleNext example