/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbcontr1.java
  ``````````````````
  Contract allocation example.
  Combining BCL problem input with problem solving 
  in Xpress-Optimizer.
  
  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, 2005, rev. Dec. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

public class xbcontr1
{
 static final int District = 6;   /* Number of districts */
 static final int Contract = 10;  /* Number of contracts */

/**** DATA ****/
 static final int[] OUTPUT = {50, 40, 10, 20, 70, 50};    
                                  /* Max. output per district */
 static final int[] COST   = {50, 20, 25, 30, 45, 40};    
                                  /* Cost per district */
 static final int[] VOLUME = {20, 10, 30, 15, 20, 30, 10, 50, 10, 20};  
                                  /* Volume of contracts */

/***********************************************************************/

 public static void main(String[] args) throws XPRSexception, XPRSprobException
 {
  int d, c, i, stat, ncol, len;
  double [] sol;
  double val;
  java.lang.String [] names;
  XPRB bcl;
  XPRBprob p;
  XPRSprob op;
  XPRBexpr l1,l2,lobj;
  XPRBvar[][] x;                  /* Variables indicating whether a project 
                                     is chosen */
  XPRBvar[][] y;                  /* Quantities allocated to contractors */

  bcl = new XPRB();               /* Initialize BCL */
  p = bcl.newProb("Contract1");   /* Create a new problem in BCL */
  XPRS.init();                    /* Initialize Xpress-Optimizer */
 
/**** VARIABLES ****/
  x = new XPRBvar[District][Contract];
  y = new XPRBvar[District][Contract];
  for(d=0;d<District;d++)
   for(c=0;c<Contract;c++)
   {
    x[d][c] = p.newVar("x_d"+ (d+1) +"_c" +(c+1), XPRB.BV);
    y[d][c] = p.newVar("q_d"+ (d+1) +"_c" +(c+1), XPRB.SC, 0, OUTPUT[d]);
    y[d][c].setLim(5);
   } 
 
/****OBJECTIVE****/
  lobj = new XPRBexpr();
  for(d=0;d<District;d++)
   for(c=0;c<Contract;c++)
    lobj.add(y[d][c].mul(COST[d]));   
     
  p.setObj(lobj);                  /* Set the objective function */
 
/**** CONSTRAINTS ****/
  for(c=0;c<Contract;c++)
  {
   l1 = new XPRBexpr();
   l2 = new XPRBexpr();  
   for(d=0;d<District;d++)
   {
    l1.add(y[d][c]);
    l2.add(x[d][c]);
   }
   p.newCtr("Size", l1.gEql(VOLUME[c]));  /* "Size": cover the req. volume */
   p.newCtr("Min", l2.gEql(2) );  /* "Min": at least 2 districts / contract */
  }
 
  for(d=0;d<District;d++)         /* Do not exceed max. output  */
  {
   l1 = new XPRBexpr();
   for(c=0;c<Contract;c++)
    l1.add(y[d][c]);
   p.newCtr("Output", l1.lEql(OUTPUT[d]) );
  } 
  
  for(d=0;d<District;d++)         /* If a contract is allocated to a district,
                                     then at least 1 unit is allocated to it */
   for(c=0;c<Contract;c++)
    p.newCtr("XY", x[d][c].lEql(y[d][c]) );

/****SOLVING + OUTPUT****/
  p.loadMat();                    /* Load the matrix explicitly */
  op = p.getXPRSprob();           /* Retrieve the Optimizer problem */
  op.mipOptimize("");             /* Solve the MIP problem */
  
  stat = op.getIntAttrib(XPRS.MIPSTATUS);
                                  /* Get the global (MIP) status */
  if((stat==XPRS.MIP_SOLUTION) || (stat==XPRS.MIP_OPTIMAL))
  {                               /* Test whether an integer sol. was found */
   val=op.getDblAttrib(XPRS.MIPOBJVAL);   
   System.out.println("Objective: " + val);

   ncol=op.getIntAttrib(XPRS.COLS); 
   sol = new double[ncol];
   op.getMipSol(sol);              /* Get the primal solution values */
   names = new java.lang.String[ncol];
   op.getNames(2, names, 0, ncol-1);  /* Get the variable names */

   for(i=0; i<ncol; i++)          /* Print out the solution */
    if(sol[i]!=0)
     System.out.print(names[i] + ": " + sol[i] + ", ");   
   System.out.println();  
  }

/* Delete the problem */
  p.finalize();              
  p=null;

 }
} 

