Initializing help system before first use

UG - Examples from 'BCL Reference Manual'


Type: Programming
Rating: 3 (intermediate)
Description: The following examples are discussed in detail in the 'BCL User Guide and Reference Manual':
  • modeling and solving a small MIP scheduling problem (xbexpl1 version BASIC)
  • using variable arrays and constraint templates (xbexpl1 versions ARRAY and ARRAYC)
  • definition of SOS-1 (xbexpl1 version SOS)
  • data input from file, index sets (xbexpl1i)
  • user error handling, output redirection (xbexpl3)
  • solving multiple scenarios of a transportation problem in parallel (xbexpl2: standard, single thread version)
  • cut generation / adding cuts at MIP tree nodes (xbcutex)
  • quadratic programming (quadratic objective: xbqpr12, quadratic constraints: xbairport)
  • combine BCL problem input with problem solving in Xpress Optimizer (xbcontr1)
  • use an Xpress Optimizer solution callback with a BCL model (xbcontr2s: single MIP thread; xbcontr2: multiple MIP threads)
File(s): xbexpl1.java, xbexpl1i.java, xbexpl3.java, xbexpl2.java, xbcutex.java, xbqpr12.java, xbairport.java, xbcontr1.java, xbcontr2.java, xbcontr2s.java
Data file(s): durations.dat


xbexpl1.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbexpl1.java
  `````````````````
  BCL user guide example.
  Definition of variables and constraints, 
  variable arrays and SOS, followed by file output,
  solving and printing of solutions.

  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, Jan. 2000, rev. Dec. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

public class xbexpl1
{
/**************************************************************************/
/* Expl 1: This example corresponds to the one printed in the             */
/*  BCL User Guide. It shows how to define variables and                  */
/*  constraints, and Special Ordered Sets, followed by file output,       */
/*  solving and printing of solutions.                                    */
/* Set the following parameter to true to try out a problem formulation   */
/* using Special Ordered Sets:                                            */

 static final boolean SOS = false;

/**************************************************************************/

 static final int NJ = 4;        /* Number of jobs */   
 static final int NT = 10;       /* Time limit */   

/**** DATA ****/
 static final double[] DUR = {3,4,2,2};   /* Durations of jobs   */ 

 static XPRBvar[] start;         /* Start times of jobs  */ 
 static XPRBvar[][] delta;       /* Binaries for start times */  
 static XPRBvar z;               /* Maximum completion time (makespan) */ 
 static XPRBsos[] set;           /* Sets regrouping start times for jobs */

 static XPRB bcl;
 static XPRBprob p; 
             
/*************************************************************************/

 static void jobsModel() throws IOException
 {
  XPRBexpr le;
  int j,t;

/****VARIABLES****/
  start = new XPRBvar[NJ];       /* Create start time variables */
  for(j=0;j<NJ;j++) start[j] = p.newVar("start");
  z = p.newVar("z",XPRB.PL,0,NT);  /* Declare the makespan variable */

  delta = new XPRBvar[NJ][NT];
  for(j=0;j<NJ;j++)              /* Declare binaries for each job  */
   for(t=0;t<(NT-DUR[j]+1);t++)
    delta[j][t] = p.newVar("delta"+(j+1)+(t+1), XPRB.BV);

/****CONSTRAINTS****/
  for(j=0;j<NJ;j++)              /* Calculate maximal completion time */
   p.newCtr("Makespan", start[j].add(DUR[j]).lEql(z) );
  
  p.newCtr("Prec", start[0].add(DUR[0]).lEql(start[2]) );
                                 /* Precedence rel. between jobs */

  for(j=0;j<NJ;j++)              /* Linking start times and binaries  */ 
  { 
   le = new XPRBexpr();
   for(t=0;t<(NT-DUR[j]+1);t++)  le.add(delta[j][t].mul((t+1))); 
   p.newCtr("Link_"+(j+1), le.eql(start[j]) );
  } 
               
  for(j=0;j<NJ;j++)              /* One unique start time for each job  */
  { 
   le = new XPRBexpr();
   for(t=0;t<(NT-DUR[j]+1);t++)  le.add(delta[j][t]); 
   p.newCtr("One_"+(j+1), le.eql(1));
  }      
              
/****OBJECTIVE****/
  p.setObj(z);                   /* Define and set objective function */ 

/****BOUNDS****/
  for(j=0;j<NJ;j++) start[j].setUB(NT-DUR[j]+1); 
                                 /* Upper bounds on start time variables */

/****OUTPUT****/
  p.print();                     /* Print out the problem definition */ 
  p.exportProb(XPRB.MPS,"expl1");   /* Output matrix to MPS file */ 
 } 

/*************************************************************************/
 static void jobsSolve()             
 { 
  int j,t,statmip; 

  if(!SOS)
   for(j=0;j<NJ;j++)    
    for(t=0;t<NT-DUR[j]+1;t++)
     delta[j][t].setDir(XPRB.PR, 10*(t+1)); 
            /* Give highest priority to variables for earlier start times */
  else
   for(j=0;j<NJ;j++)    
    set[j].setDir(XPRB.DN);       /* First branch downwards on sets */

  p.setSense(XPRB.MINIM);
  p.mipOptimize("");              /* Solve the problem as MIP */
  statmip = p.getMIPStat();       /* Get the MIP problem status */    
              
  if((statmip == XPRB.MIP_SOLUTION) || (statmip == XPRB.MIP_OPTIMAL))
                                  /* An integer solution has been found */
  {  
   System.out.println("Objective: "+ p.getObjVal()); 
   for(j=0;j<NJ;j++) 
   {                              /* Print the solution for all start times */
    System.out.println(start[j].getName() + ": "+ start[j].getSol()); 
    for(t=0;t<NT-DUR[j]+1;t++) 
     System.out.print(delta[j][t].getName() + ": "+ delta[j][t].getSol());
    System.out.println();
   }
  } 
 }

/*************************************************************************/

 public static void main(String[] args)
 {         
  bcl = new XPRB();              /* Initialize BCL */
  p = bcl.newProb("Jobs");       /* Create a new problem */
  
  try
  {
   if(!SOS)
    jobsModel();                 /* Basic problem definition */
   else
    jobsModelb();                /* Formulation using SOS */
  }
  catch(IOException e)
  {
   System.err.println(e.getMessage());
   System.exit(1);
  }
  
  jobsSolve();                   /* Solve and print solution */

  p.finalize();                  /* Delete the problem */      
  p=null;
 }

/*************************************************************************/

 static void jobsModelb() throws IOException    /**** SOS-formulation ****/
 {
  XPRBexpr le;
  int j,t;

/****VARIABLES****/
  start = new XPRBvar[NJ];         /* Create start time variables */
  for(j=0;j<NJ;j++) start[j] = p.newVar("start");
  z = p.newVar("z",XPRB.PL,0,NT);  /* Declare the makespan variable */

  delta = new XPRBvar[NJ][NT];
  for(j=0;j<NJ;j++)             /* Declare binaries for each job  */
   for(t=0;t<(NT-DUR[j]+1);t++)
    delta[j][t] = p.newVar("delta"+(j+1)+(t+1), XPRB.PL, 0,1);

/****CONSTRAINTS****/
  for(j=0;j<NJ;j++)             /* Calculate maximal completion time */
   p.newCtr("Makespan", start[j].add(DUR[j]).lEql(z));
  
  p.newCtr("Prec", start[0].add(DUR[0]).lEql(start[2]) );
                                /* Precedence rel. betw. jobs */

  for(j=0;j<NJ;j++)             /* Linking start times and binaries  */ 
  { 
   le = new XPRBexpr();
   for(t=0;t<(NT-DUR[j]+1);t++)  le.add(delta[j][t].mul((t+1))); 
   p.newCtr("Link_"+(j+1), le.eql(start[j]) );
  } 
              
  for(j=0;j<NJ;j++)             /* One unique start time for each job  */
  { 
   le = new XPRBexpr();
   for(t=0;t<(NT-DUR[j]+1);t++)  le.add(delta[j][t]); 
   p.newCtr("One_"+(j+1), le.eql(1));
  }         
              
/****OBJECTIVE****/
  p.setObj(z);                  /* Define and set objective function */ 

/****BOUNDS****/
  for(j=0;j<NJ;j++) start[j].setUB(NT-DUR[j]+1); 
                                /* Upper bounds on start time variables */

/****SETS****/
  set = new XPRBsos[NJ];
  for(j=0;j<NJ;j++)  
  {
   le = new XPRBexpr();
   for(t=0;t<(NT-DUR[j]+1);t++)  le.add(delta[j][t].mul((t+1)));
   set[j] = p.newSos("sosj", XPRB.S1, le);
  } 

/****OUTPUT****/
  p.print();                    /* Print out the problem definition */ 
  p.exportProb(XPRB.MPS,"expl1");  /* Output matrix to MPS file */ 
 } 
}

xbexpl1i.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbexpl1i.java
  ``````````````````
  BCL user guide example.
  Version using index sets.

  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, 2003, rev. Dec. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

public class xbexpl1i
{
 static final String DATAFILE = System.getProperty("XPRBDATA") + 
   "/jobs/durations.dat";

 static final int MAXNJ = 4;     /* Max. number of jobs */   
 static final int NT = 10;       /* Time limit */   

/**** DATA ****/
 static int NJ = 0;              /* Number of jobs read in */
 static double[] DUR;            /* Durations of jobs   */ 

 static XPRBindexSet Jobs;	 /* Job names */
 static XPRBvar[] start;         /* Start times of jobs  */ 
 static XPRBvar[][] delta;       /* Binaries for start times */  
 static XPRBvar z;               /* Maximum completion time (makespan) */ 

 static XPRB bcl;
 static XPRBprob p; 
             
/*************************************************************************/

    /**** Initialize the stream tokenizer ****/
 static StreamTokenizer initST(FileReader file)
 {
  StreamTokenizer st=null;

  st= new StreamTokenizer(file);   /* Initialize the stream tokenizer */
  st.commentChar('!');             /* Use the character '!' for comments */
  st.eolIsSignificant(true);       /* Return end-of-line character */
  st.ordinaryChar(',');            /* Use ',' as separator */
  st.parseNumbers();               /* Read numbers as numbers (not strings)*/ 
  return st;
 }

    /**** Read data from files ****/
 static void readData() throws IOException
 {
  FileReader datafile=null;
  StreamTokenizer st;
  int i;
 
                                   /* Create a new index set */
  Jobs = p.newIndexSet("Jobs", MAXNJ);
  DUR = new double[MAXNJ];
  
        /* Read the durations data file */
  datafile = new FileReader(DATAFILE);
  st = initST(datafile);
  do
  {
   do
   { 
    st.nextToken();
   } while(st.ttype==st.TT_EOL);    /* Skip empty lines */
   if(st.ttype != st.TT_WORD) break; 
   i=Jobs.addElement(st.sval);
   if(st.nextToken() != ',') break;
   if(st.nextToken() != st.TT_NUMBER) break;
   DUR[i] = st.nval;
   NJ+=1;
  } while( st.nextToken() == st.TT_EOL && NJ<MAXNJ);
  datafile.close();
  System.out.println("Number of jobs read: " + Jobs.getSize());
 }

/***********************************************************************/
 static void jobsModel()
 {
  XPRBexpr le;
  int j,t;

/****VARIABLES****/
  start = new XPRBvar[NJ];    /* Create start time variables (incl. bounds) */
  for(j=0;j<NJ;j++) start[j] = p.newVar("start", XPRB.PL, 0, NT-DUR[j]+1);
  z = p.newVar("z",XPRB.PL,0,NT);  /* Declare the makespan variable */

  delta = new XPRBvar[NJ][NT];
  for(j=0;j<NJ;j++)              /* Declare binaries for each job  */
   for(t=0;t<(NT-DUR[j]+1);t++)
    delta[j][t] = p.newVar("delta"+Jobs.getIndexName(j)+"_"+(t+1), XPRB.BV);

/****CONSTRAINTS****/
  for(j=0;j<NJ;j++)              /* Calculate maximal completion time */
   p.newCtr("Makespan", start[j].add(DUR[j]).lEql(z) );
  
  p.newCtr("Prec", start[0].add(DUR[0]).lEql(start[2]) );
                                 /* Precedence rel. between jobs */

  for(j=0;j<NJ;j++)              /* Linking start times and binaries  */ 
  { 
   le = new XPRBexpr();
   for(t=0;t<(NT-DUR[j]+1);t++)  le.add(delta[j][t].mul((t+1))); 
   p.newCtr("Link_"+(j+1), le.eql(start[j]) );
  } 
               
  for(j=0;j<NJ;j++)              /* One unique start time for each job  */
  { 
   le = new XPRBexpr();
   for(t=0;t<(NT-DUR[j]+1);t++)  le.add(delta[j][t]); 
   p.newCtr("One_"+(j+1), le.eql(1));
  }      
              
/****OBJECTIVE****/
  p.setObj(z);                   /* Define and set objective function */ 

/****BOUNDS****/
  for(j=0;j<NJ;j++) start[j].setUB(NT-DUR[j]+1); 
                                 /* Upper bounds on start time variables */
 } 

/*************************************************************************/
 static void jobsSolve()             
 { 
  int j,t,statmip; 

  for(j=0;j<NJ;j++)    
   for(t=0;t<NT-DUR[j]+1;t++)
    delta[j][t].setDir(XPRB.PR, 10*(t+1)); 
            /* Give highest priority to variables for earlier start times */

  p.setSense(XPRB.MINIM);
  p.mipOptimize("");              /* Solve the problem as MIP */
  statmip = p.getMIPStat();       /* Get the MIP problem status */    
              
  if((statmip == XPRB.MIP_SOLUTION) || (statmip == XPRB.MIP_OPTIMAL))
                                  /* An integer solution has been found */
  {  
   System.out.println("Objective: "+ p.getObjVal()); 
   for(j=0;j<NJ;j++) 
   {                              /* Print the solution for all start times */
    System.out.println(start[j].getName() + ": "+ start[j].getSol()); 
    for(t=0;t<NT-DUR[j]+1;t++) 
     System.out.print(delta[j][t].getName() + ": "+ delta[j][t].getSol() + " ");
    System.out.println();
   }
  } 
 }

/*************************************************************************/

 public static void main(String[] args)
 {         
  bcl = new XPRB();              /* Initialize BCL */
  p = bcl.newProb("Jobs");       /* Create a new problem */

  try
  {
   readData();                   /* Data input from file */
  }
  catch(IOException e)
  {
   System.err.println(e.getMessage());
   System.exit(1);
  }
  jobsModel();                   /* Problem definition */

  jobsSolve();                   /* Solve and print solution */

  p.finalize();                  /* Delete the problem */      
  p=null;
 }
}

xbexpl3.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbexpl3.java
  `````````````````
  Error handling and output redirection.

  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, 2005, rev. Jan. 2012
********************************************************/

import java.io.*;
import com.dashoptimization.*;

/* This small, infeasible example shows how all printed messages can 
   be intercepted by the user's program. */

public class xbexpl3
{
 static XPRB bcl;

/***********************************************************************/

 public static void modexpl3(XPRBprob prob) throws XPRBerror
 {
  XPRBvar[] x;
  XPRBexpr cobj;
  int i;

  x = new XPRBvar[3];                 /* Create the variables */
  for(i=0;i<2;i++) x[i] = prob.newVar("x_"+i, XPRB.UI, 0, 100);

                /* Create the constraints:
                   C1: 2x0 + 3x1 >= 41
                   C2:  x0 + 2x1  = 13 */
  prob.newCtr("C1", x[0].mul(2).add(x[1].mul(3)) .gEql(41));
  prob.newCtr("C2", x[0].add(x[1].mul(2)) .eql(13));

/* Uncomment the following line to cause an error in the model that
   triggers the error handling: */

//  x[2] = prob.newVar("x_2", XPRB.UI, 10, 1); 
 
                /* Objective: minimize x0+x1 */
  cobj = new XPRBexpr(); 
  for(i=0;i<2;i++) cobj.add(x[i]); 
  prob.setObj(cobj);             /* Select objective function */ 
  prob.setSense(XPRB.MINIM);     /* Set objective sense to minimization */ 

  prob.print();                  /* Print current problem definition */

  prob.lpOptimize("");           /* Solve the LP */
  System.out.println("Problem status: " + prob.getProbStat() +
                     "  LP status: " + prob.getLPStat() + 
                     "  MIP status: " + prob.getMIPStat());

/* This problem is infeasible, that means the following command will fail.
   It prints a warning if the message level is at least 2 */
   
  System.out.println("Objective: " + prob.getObjVal());

  for(i=0;i<2;i++)               /* Print solution values */ 
   System.out.print(x[i].getName() + ":" + x[i].getSol() + ", ");
  System.out.println();
}

/***********************************************************************/

 public static void main(String[] args)
 {
  FileWriter f;
  XPRBprob prob;

  try
  {
   bcl = new XPRB();             /* Initialize BCL */
  }
  catch(XPRBlicenseError e)
  {
   System.err.println("BCL error "+ e.getErrorCode() + ": " + e.getMessage());
   System.exit(1);
  } 

  bcl.setMsgLevel(2);            /* Set the printing flag. Try other values:
                                    0 - no printed output,
                                    2 - print warnings, 3 - all messages */
  try
  {
   f=new FileWriter("expl3out.txt");
   bcl.setOutputStream(f);       /* Redirect all output from BCL to a file */

   prob = bcl.newProb("Expl3");  /* Create a new problem */
   prob.setOutputStream();       /* Output for this prob. on standard output */
   modexpl3(prob);               /* Formulate and solve the problem */

   prob.setOutputStream(f);      /* Redirect problem output to file */
   prob.print();                 /* Write to the output file */
   prob.setOutputStream();       /* Re-establish standard output for prob */
   bcl.setOutputStream();        /* Re-establish standard output for BCL */
   f.close();

   prob.finalize();              /* Delete the problem */
   prob=null;
  
   bcl.finalize();               /* Release license */
   bcl=null;

   System.gc();                  /* Force garbage collection */
   System.runFinalization();

   System.err.flush();
  }
  catch(IOException e)
  {
   System.err.println(e.getMessage());
   System.exit(1);   
  }
  catch(XPRBerror e)
  {
   System.err.println("BCL error "+ e.getErrorCode() + ": " + e.getMessage());
   System.exit(1);
  } 
 } 
} 

xbexpl2.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbexpl2.java
  `````````````````
  Transportation model demonstrating use of index sets.

  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, Jan. 2000, rev. Dec. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

public class xbexpl2
{
 static final int MaxSuppliers = 100; /* Max. number of suppliers */
 static final int MaxCustomers = 1000;/* Max. number of customers */
 static final int MaxArcs = 10000;    /* Max. number of non-zero cost values */
 static final String DEMANDFILE = System.getProperty("XPRBDATA") + 
   "/trans/ex2dem1.dat";  
                                /* Demand data file (comma-separated format) */
 static final String AVAILFILE = System.getProperty("XPRBDATA") + 
   "/trans/ex2avail.dat"; 
                                /* Supply data file (comma-separated format) */
 static final String COSTFILE = System.getProperty("XPRBDATA") + 
   "/trans/ex2cost.dat";   
                                /* Cost data file (comma-separated format) */

 static XPRBindexSet Suppliers; /* Set of suppliers */
 static XPRBindexSet Customers; /* Set of customers */
 static double[] AVAIL;         /* Availability of products */
 static double[] DEMAND;        /* Demand by customers */

 static class TData {
        int suppl;
        int custm;
        double value;
 };
 
 static TData[] COST = new TData[MaxArcs]; /* Cost per supplier-customer pair*/

 static int NSuppl=0, NCustom=0, NArc=0;   /* Actual numbers of suppliers,
                                              customers, and arcs */

 static XPRB bcl;
 static XPRBprob p;

/***********************************************************************/

 static void modTrans() throws IOException
 {
  XPRBexpr lobj, av[], de[];
  int s,c,a;
  XPRBvar[] x;
 
/****VARIABLES****/
  x = new XPRBvar[NArc];
  for(a=0; a<NArc; a++) x[a]=p.newVar("x");
     
/****OBJECTIVE****/ 
  lobj = new XPRBexpr();
  for(a=0; a<NArc; a++)
   lobj.add(x[a].mul(COST[a].value));
  p.setObj(lobj);                  /* Set objective function */ 

/****CONSTRAINTS****/
    /**** Create all constraints in a single loop ****/
                                   /* Initialize the linear expressions */
  av = new XPRBexpr[NSuppl];
  for(s=0; s<NSuppl; s++) av[s] = new XPRBexpr();
  de = new XPRBexpr[NCustom];
  for(c=0; c<NCustom; c++) de[c] = new XPRBexpr();

  for(a=0; a<NArc; a++)            /* Add terms to expressions one-by-one */
  {
   av[COST[a].suppl].add(x[a]);
   de[COST[a].custm].add(x[a]);
  }                                 
                                   /* Terminate the constraint definition */
  for(s=0; s<NSuppl; s++)  p.newCtr("Avail", av[s].lEql(AVAIL[s]) );
  for(c=0; c<NCustom; c++)  p.newCtr("Demand", de[c].gEql(DEMAND[c]) );

/****SOLVING + OUTPUT****/
  p.exportProb(XPRB.MPS,"trans");  /* Matrix generation & output to MPS file */

  p.lpOptimize("");                /* Solve the LP-problem */
  System.out.println("Objective: " + p.getObjVal());  /* Get objective value */

  for(a=0; a<NArc; a++)            /* Print out the solution values */
  if(x[a].getSol()>0)
   System.out.println(Suppliers.getIndexName(COST[a].suppl) + " (" +
     AVAIL[COST[a].suppl] + ") -> " + Customers.getIndexName(COST[a].custm)
      + " (" + DEMAND[COST[a].custm] + "): " + x[a].getSol());  
}

/***********************************************************************/

    /**** Initialize the stream tokenizer ****/
 static StreamTokenizer initST(FileReader file)
 {
  StreamTokenizer st=null;

  st= new StreamTokenizer(file);   /* Initialize the stream tokenizer */
  st.commentChar('!');             /* Use the character '!' for comments */
  st.eolIsSignificant(true);       /* Return end-of-line character */
  st.ordinaryChar(',');            /* Use ',' as separator */
  st.parseNumbers();               /* Read numbers as numbers (not strings)*/ 
  return st;
 }

    /**** Read data from files ****/
 static void readData() throws IOException
 {
  FileReader datafile=null;
  StreamTokenizer st;
  int i;
 
        /* Create supplier and customer index sets */
  Suppliers = p.newIndexSet("suppl", MaxSuppliers);
  Customers = p.newIndexSet("custom", MaxCustomers);
  AVAIL = new double[MaxSuppliers];
  DEMAND = new double[MaxCustomers];
  
        /* Read the demand data file */
  datafile = new FileReader(DEMANDFILE);
  st = initST(datafile);
  do
  {
   do
   { 
    st.nextToken();
   } while(st.ttype==st.TT_EOL);    /* Skip empty lines */
   if(st.ttype != st.TT_WORD) break; 
   i=Customers.addElement(st.sval);
   if(st.nextToken() != ',') break;
   if(st.nextToken() != st.TT_NUMBER) break;
   DEMAND[i] = st.nval;
  } while( st.nextToken() == st.TT_EOL );
  datafile.close();
  NCustom = Customers.getSize();

        /* Read the supply data file */
  datafile = new FileReader(AVAILFILE);
  st = initST(datafile);
  do
  {
   do
   { 
    st.nextToken();
   } while(st.ttype==st.TT_EOL);
   if(st.ttype != st.TT_WORD) break; 
   i=Suppliers.addElement(st.sval);
   if(st.nextToken() != ',') break;
   if(st.nextToken() != st.TT_NUMBER) break;
   AVAIL[i] = st.nval;
  } while( st.nextToken() == st.TT_EOL );
  datafile.close();
  NSuppl = Suppliers.getSize();

        /* Read the cost data file */
  NArc = 0;
  datafile = new FileReader(COSTFILE);
  st = initST(datafile);
  do                     /* Read the cost data file and fill the index sets */
  {
   do
   { 
    st.nextToken();
   } while(st.ttype==st.TT_EOL);    /* Skip empty lines */
   if(st.ttype != st.TT_WORD) break;
   COST[NArc]=new TData();   
   COST[NArc].suppl=Suppliers.getIndex(st.sval);
   if(COST[NArc].suppl<0) System.out.println("Supp(" + st.sval + ")");
   if(st.nextToken() != ',') break;
   if(st.nextToken() != st.TT_WORD) break;
   COST[NArc].custm=Customers.getIndex(st.sval);
   if(COST[NArc].custm<0) System.out.println("Cust(" + st.sval + ")");
   if(st.nextToken() != ',') break;
   if(st.nextToken() != st.TT_NUMBER) break;
   COST[NArc++].value = st.nval;
  } while( st.nextToken() == st.TT_EOL );
    datafile.close();

  System.out.println("C: " + NCustom + "  S: " + NSuppl + "  A: " + NArc);
 }

/***********************************************************************/

 public static void main(String[] args)
 {
  bcl = new XPRB();                /* Initialize BCL */
  p = bcl.newProb("Trans");        /* Create a new problem in BCL */ 
  try
  {
   readData();                     /* Data input from file */
   modTrans();                     /* Formulate and solve the problem */
  }
  catch(IOException e)
  {
   System.err.println(e.getMessage());
   System.exit(1);
  }

  p.finalize();                    /* Delete the problem */      
  p=null;
 }
} 

xbcutex.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbcutex.java
  `````````````````
  Simplified version of xbexpl1.java showing how 
  to define cuts with BCL.

  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, 2005, rev. Dec. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

public class xbcutex
{
 static final int NJ = 4;        /* Number of jobs */   
 static final int NT = 10;       /* Time limit */   

/**** DATA ****/
 static final double[] DUR = {3,4,2,2};   /* Durations of jobs   */ 

 static XPRBvar[] start;         /* Start times of jobs  */ 
 static XPRBvar[][] delta;       /* Binaries for start times */  
 static XPRBvar z;               /* Maximum completion time (makespan) */ 

 static XPRB bcl;
 static XPRBprob p; 
             
/*************************************************************************/

 static class CutMgrCallback implements XPRScutMgrListener
 {
  public int XPRScutMgrEvent(XPRSprob oprob, Object data)
  {
   XPRBprob bprob;
   XPRBcut[] ca;
   int num,i;

   bprob = (XPRBprob)data;       /* Get the BCL problem */

   try 
   {   
    bprob.beginCB(oprob);
    num = oprob.getIntAttrib(XPRS.NODES);
    if(num == 2)                 /* Only generate cuts at node 2 */
    {
     ca = new XPRBcut[2];
     ca[0] = bprob.newCut(start[1].add(2) .lEql(start[0]), 2); 
     ca[1] = bprob.newCut(start[2].mul(4) .add(start[3].mul(-5.3)) .lEql(-17), 2);
     System.out.println("Adding constraints:");
     for(i=0;i<2;i++) ca[i].print();
     bprob.addCuts(ca);
    }
    bprob.endCB();
   }
   catch(XPRSprobException e)
   {
    System.out.println("Error  " + e.getCode() + ": " + e.getMessage());
   } 
   return 0;                     /* Call this method once per node */
  }
 }

/*************************************************************************/

 static void jobsModel()
 {
  XPRBexpr le;
  int j,t;

/****VARIABLES****/
  start = new XPRBvar[NJ];       /* Create start time variables */
  for(j=0;j<NJ;j++) start[j] = p.newVar("start");
  z = p.newVar("z",XPRB.PL,0,NT);  /* Declare the makespan variable */

  delta = new XPRBvar[NJ][NT];
  for(j=0;j<NJ;j++)              /* Declare binaries for each job  */
   for(t=0;t<(NT-DUR[j]+1);t++)
    delta[j][t] = p.newVar("delta"+(j+1)+(t+1), XPRB.BV);

/****CONSTRAINTS****/
  for(j=0;j<NJ;j++)              /* Calculate maximal completion time */
   p.newCtr("Makespan", start[j].add(DUR[j]).lEql(z) );
  
  p.newCtr("Prec", start[0].add(DUR[0]).lEql(start[2]) );
                                 /* Precedence rel. between jobs */

  for(j=0;j<NJ;j++)              /* Linking start times and binaries  */ 
  { 
   le = new XPRBexpr();
   for(t=0;t<(NT-DUR[j]+1);t++)  le.add(delta[j][t].mul((t+1))); 
   p.newCtr("Link_"+(j+1), le.eql(start[j]) );
  } 
               
  for(j=0;j<NJ;j++)              /* One unique start time for each job  */
  { 
   le = new XPRBexpr();
   for(t=0;t<(NT-DUR[j]+1);t++)  le.add(delta[j][t]); 
   p.newCtr("One_"+(j+1), le.eql(1));
  }      
              
/****OBJECTIVE****/
  p.setObj(z);                   /* Define and set objective function */ 

/****BOUNDS****/
  for(j=0;j<NJ;j++) start[j].setUB(NT-DUR[j]+1); 
                                 /* Upper bounds on start time variables */

/****OUTPUT****/
  p.print();                     /* Print out the problem definition */ 
 } 

/*************************************************************************/

 static void jobsSolve() throws XPRSexception       
 { 
  int j,t,statmip; 
  XPRSprob oprob;
  CutMgrCallback cb;

  oprob = p.getXPRSprob();        /* Get Optimizer problem */
  oprob.setIntControl(XPRS.HEURSTRATEGY, 0);
  oprob.setIntControl(XPRS.CUTSTRATEGY, 0);
                                  /* Switch automated cut generation off:
                                     otherwise this problem is solved in the
                                     first node of the MIP search tree */

  p.setCutMode(1);                /* Switch presolve off, enable cut manager */
  cb = new CutMgrCallback();
  oprob.addCutMgrListener(cb, p);

  p.setSense(XPRB.MINIM);
  p.mipOptimize("");              /* Solve the problem as MIP */
  statmip = p.getMIPStat();       /* Get the MIP problem status */    
              
  if((statmip == XPRB.MIP_SOLUTION) || (statmip == XPRB.MIP_OPTIMAL))
                                  /* An integer solution has been found */
  {  
   System.out.println("Objective: "+ p.getObjVal()); 
   for(j=0;j<NJ;j++) 
   {                              /* Print the solution for all start times */
    System.out.println(start[j].getName() + ": "+ start[j].getSol()); 
    for(t=0;t<NT-DUR[j]+1;t++) 
     System.out.print(delta[j][t].getName() + ": "+ delta[j][t].getSol());
    System.out.println();
   }
  } 
 }

/*************************************************************************/

 public static void main(String[] args) throws XPRSexception
 {         
  bcl = new XPRB();              /* Initialize BCL */
  p = bcl.newProb("Jobs");       /* Create a new problem */
  XPRS.init();                   /* Initialize Xpress-Optimizer */
  
  jobsModel();                   /* Basic problem definition */
    
  try
  {
   jobsSolve();                  /* Solve and print solution */
  }
  catch(XPRSexception e)
  {
   System.err.println(e.getMessage());
   System.exit(1);
  }

  p.finalize();                  /* Delete the problem */           
  p=null;
 }
}

xbqpr12.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbqpr12.java
  `````````````````
  Small Quadratic Programming example.
       minimize x1 + x1^2 +2x1x2 +2x2^2 +x4^2
       s.t. C1:  x1 +2x2 -4x4 >= 0
            C2: 3x1 -2x3 - x4 <= 100
            C3: 10 <= x1 +3x2 +3x3 -2x4 <= 30
            0<=x1<=20
            0<=x2,x3
            x4 free

  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, Jan. 2000, rev. Dec. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

public class xbqpr12
{
 static final int NXPRBvar = 4;

/***********************************************************************/

 public static void main(String[] args) throws IOException
 {
  XPRB bcl;
  XPRBctr c;
  XPRBexpr le, qobj;
  XPRBvar[] x;
  int i;
  XPRBprob p;
  
  bcl = new XPRB();               /* Initialize BCL */
  p = bcl.newProb("QPr12");       /* Create a new problem in BCL */

/**** VARIABLES ****/
  x = new XPRBvar[NXPRBvar];
  x[0] = p.newVar("x1", XPRB.PL, 0, 20);
  x[1] = p.newVar("x2");
  x[2] = p.newVar("x3");
  x[3] = p.newVar("x4", XPRB.PL, -XPRB.INFINITY, XPRB.INFINITY);

/****OBJECTIVE****/
  qobj = new XPRBexpr();          /* Define the objective function */
  qobj.add(x[0]);
  qobj.add( (x[0].sqr()) .add(x[0].mul(2).mul(x[1]))
   .add(x[1].sqr().mul(2)) .add(x[3].sqr()) );
  p.setObj(qobj);
 
/**** CONSTRAINTS ****/
  p.newCtr("C1", x[0].add(x[1].mul(2)).add(x[3].mul(-4)) .gEql(0) );
  p.newCtr("C2", x[0].mul(3).add(x[2].mul(-2)).add(x[3].mul(-1)) .lEql(100) );
  c = p.newCtr("C3", x[0].add(x[1].mul(3)) .add(x[2].mul(3)) 
      .add(x[3].mul(-2)) );
  c.setRange(10,30);
   
/****SOLVING + OUTPUT****/
  p.print();			  /* Print out the problem definition */
  p.exportProb(XPRB.MPS,"QPr12"); /* Output the matrix in MPS format */
  p.exportProb(XPRB.LP,"QPr12");  /* Output the matrix in LP format */
  
  p.setSense(XPRB.MINIM);         /* Choose the sense of the  optimization */   
  p.lpOptimize("");               /* Solve the QP-problem */

  System.out.println("Objective function value: " + p.getObjVal());
  for(i=0;i<NXPRBvar;i++)
   System.out.print(x[i].getName() + ": " +  x[i].getSol() + ", ");
  System.out.println();


  p.finalize();                   /* Delete the problem */      
  p=null;
 } 
}

xbairport.java
/********************************************************
  BCL Example Problems
  ====================

  file xbairport.java
  ```````````````````
  QCQP problem by
      Rodrigo de Barros Nabholz & Maria Aparecida Diniz Ehrhardt
      November 1994, DMA - IMECC- UNICAMP.
  Based on AMPL model airport.mod by Hande Y. Benson
  (Source: http://www.orfe.princeton.edu/~rvdb/ampl/nlmodels/ )
   
  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, June 2008, rev. Dec. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

public class xbairport
{
 static final int N = 42;

 static final double CX[] = {-6.3, -7.8, -9, -7.2, -5.7, -1.9, -3.5, -0.5, 1.4,
              4, 2.1, 5.5, 5.7, 5.7, 3.8, 5.3, 4.7, 3.3, 0, -1, -0.4, 4.2, 
              3.2, 1.7, 3.3, 2, 0.7, 0.1, -0.1, -3.5, -4, -2.7, -0.5, -2.9,
              -1.2, -0.4, -0.1, -1, -1.7, -2.1, -1.8, 0};
 static final double CY[] = {8, 5.1, 2, 2.6, 5.5, 7.1, 5.9, 6.6, 6.1, 5.6, 4.9, 
              4.7, 4.3, 3.6, 4.1, 3, 2.4, 3, 4.7, 3.4, 2.3, 1.5, 0.5, -1.7, -2,
              -3.1, -3.5, -2.4, -1.3, 0, -1.7, -2.1, -0.4, -2.9, -3.4, -4.3,
              -5.2, -6.5, -7.5, -6.4, -5.1, 0};
 static final double R[] = {0.09, 0.3, 0.09, 0.45, 0.5, 0.04, 0.1, 0.02, 0.02,  
              0.07, 0.4, 0.045, 0.05, 0.056, 0.36, 0.08, 0.07, 0.36, 0.67, 0.38,
              0.37, 0.05, 0.4, 0.66, 0.05, 0.07, 0.08, 0.3, 0.31, 0.49, 0.09, 
              0.46, 0.12, 0.07, 0.07, 0.09, 0.05, 0.13, 0.16, 0.46, 0.25, 0.1};

 public static void main(String[] args) throws IOException
 {
  XPRB bcl;
  XPRBprob prob;
  int i,j;
  XPRBvar[] x,y;                        /* x-/y-coordinates to determine */
  XPRBexpr qe;
  XPRBctr cobj, c;

  bcl = new XPRB();                     /* Initialize BCL */
  prob = bcl.newProb("airport");        /* Create a new problem in BCL */

/**** VARIABLES ****/
  x = new XPRBvar[N];
  for(i=0;i<N;i++) 
   x[i] = prob.newVar("x(" + (i+1) + ")", XPRB.PL, -10, 10);
  y = new XPRBvar[N];
  for(i=0;i<N;i++) 
   y[i] = prob.newVar("y(" + (i+1) + ")", XPRB.PL, -10, 10);

/****OBJECTIVE****/
/* Minimize the total distance between all points */
/*  sum(i in 1..N-1,j in i+1..N) ((x(i)-x(j))^2+(y(i)-y(j))^2)  */
  qe = new XPRBexpr();
  for(i=0;i<N-1;i++)
   for(j=i+1;j<N;j++) qe .add((x[i].add(x[j].mul(-1))).sqr()) 
                         .add((y[i].add(y[j].mul(-1))).sqr());
  cobj = prob.newCtr("TotDist", qe);
  prob.setObj(cobj);                     /* Set objective function */ 

/**** CONSTRAINTS ****/
/* All points within given distance of their target location */
/*  (x(i)-CX(i))^2+(y(i)-CY(i))^2 <= R(i)  */
  for(i=0;i<N;i++)
   c = prob.newCtr("LimDist", (x[i].add(-CX[i])).sqr() 
                   .add( (y[i].add(-CY[i])).sqr()) .lEql(R[i]) );
 
/****SOLVING + OUTPUT****/
  prob.setSense(XPRB.MINIM);             /* Choose the sense of optimization */
 
/* Problem printing and matrix output: */
/*
  prob.print(); 
  prob.exportProb(XPRB.MPS, "airport");
  prob.exportProb(XPRB.LP, "airport");
*/

  prob.lpOptimize("");                   /* Solve the problem */

  System.out.println("Solution: " + prob.getObjVal());
  for(i=0;i<N;i++)
   System.out.println(x[i].getName() + ": " + x[i].getSol() + ", " +
                      y[i].getName() + ": " + y[i].getSol());

/* Delete the problem */
  prob.finalize();              
  prob=null;
 }
}  

xbcontr1.java
/********************************************************
  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;

 }
} 


xbcontr2.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbcontr2.java
  ``````````````````
  Contract allocation example.
  Combining BCL problem input with problem solving 
  and callbacks in Xpress-Optimizer.
  
  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, 2005, rev. Dec. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

public class xbcontr2
{
 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 */

 /***********************************************************************/

 static class IntSolCallback implements XPRSintSolListener
 {
  public void XPRSintSolEvent(XPRSprob oprob, Object data)
  {
   int num, d, c;
   XPRBprob bprob;   
   XPRBvar y;

   try {
    bprob = (XPRBprob)data;
    bprob.beginCB(oprob);
    num = oprob.getIntAttrib(XPRS.MIPSOLS);  /* Get number of the solution */
    bprob.sync(XPRB.XPRS_SOL);               /* Update BCL solution values */
  
    System.out.println("Solution " + num + ": Objective value: " +
                       bprob.getObjVal());

    for(d=0;d<District;d++)
     for(c=0;c<Contract;c++)
     {
      y = bprob.getVarByName("q_d"+ (d+1) + "_c" + (c+1));
      if( (y.getColNum()>-1) && (y.getSol() != 0))
       System.out.println(y.getName() + ": " + y.getSol()); 
     }
    bprob.endCB();
   }
   catch(XPRSprobException e) {
    System.out.println("Error " + e.getCode() + ": " + e.getMessage());
   }
  }
 }
 
 /***********************************************************************/

 public static void main(String[] args) throws XPRSexception
 {
  int d, c, i, stat, ncol, len;
  double [] sol;
  double val;
  java.lang.String [] names;
  XPRB bcl;
  XPRBprob p;
  XPRSprob op;
  IntSolCallback cb;
  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("Contract2");   /* 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****/
  cb = new IntSolCallback();
  p.getXPRSprob().addIntSolListener(cb,p);
                                  /* Define an integer solution callback */
  p.mipOptimize("");              /* Solve the MIP problem */

/* Delete the problem */
  p.finalize();              
  p=null;

 }
} 

xbcontr2s.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbcontr2s.java
  ```````````````````
  Contract allocation example.
  Combining BCL problem input with problem solving 
  and callbacks in Xpress-Optimizer.
  -- Single MIP thread --
  
  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, 2005, rev. Dec. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

public class xbcontr2s
{
 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 */

 /***********************************************************************/

 static class IntSolCallback implements XPRSintSolListener
 {
  public void XPRSintSolEvent(XPRSprob oprob, Object data)
  {
   int num, d, c;
   XPRBprob bprob;   
   XPRBvar y;

   try {
    bprob = (XPRBprob)data;
    num = oprob.getIntAttrib(XPRS.MIPSOLS);  /* Get number of the solution */
    bprob.sync(XPRB.XPRS_SOL);               /* Update BCL solution values */
  
    System.out.println("Solution " + num + ": Objective value: " +
                       bprob.getObjVal());

    for(d=0;d<District;d++)
     for(c=0;c<Contract;c++)
     {
      y = bprob.getVarByName("q_d"+ (d+1) + "_c" + (c+1));
      if( (y.getColNum()>-1) && (y.getSol() != 0))
       System.out.println(y.getName() + ": " + y.getSol()); 
     }
   }
   catch(XPRSprobException e) {
    System.out.println("Error " + e.getCode() + ": " + e.getMessage());
   }
  }
 }
 
 /***********************************************************************/

 public static void main(String[] args) throws XPRSexception
 {
  int d, c, i, stat, ncol, len;
  double [] sol;
  double val;
  java.lang.String [] names;
  XPRB bcl;
  XPRBprob p;
  XPRSprob op;
  IntSolCallback cb;
  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("Contract2");   /* 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****/
     /* Desactivate parallel MIP (for synchronization of BCL and Optimizer) */
  p.getXPRSprob().setIntControl(XPRS.MIPTHREADS, 1);

  cb = new IntSolCallback();
  p.getXPRSprob().addIntSolListener(cb,p);
                                  /* Define an integer solution callback */
  p.mipOptimize("");              /* Solve the MIP problem */

/* Delete the problem */
  p.finalize();              
  p=null;

 }
}