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

UG - Examples from 'BCL Reference Manual'

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.c version BASIC)
  • using variable arrays and constraint templates (xbexpl1.c 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; xbscenar: defining multiple problems, each in a separate thread)
  • 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)
Further explanation of this example: 'BCL Reference Manual', Appendix B Using BCL with the Optimizer library


Source Files

Data Files





xbexpl2.c

/********************************************************
  BCL Example Problems
  ====================

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

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

#include <stdio.h>
#include <stdlib.h>
#include "xprb.h"

#define MaxSuppliers 100         /* Max. number of suppliers */
#define MaxCustomers 1000        /* Max. number of customers */
#define MaxArcs 10000            /* Max. number of non-zero cost values */

#define DEMANDFILE XPRBDATAPATH "/trans/ex2dem1.dat"
                                 /* Demand data file (comma-separated format) */
#define AVAILFILE XPRBDATAPATH "/trans/ex2avail.dat"
                                 /* Supply data file (comma-separated format) */
#define COSTFILE XPRBDATAPATH "/trans/ex2cost.dat"
                                 /* Cost data file (comma-separated format) */

XPRBidxset Suppliers;            /* Set of suppliers */
XPRBidxset Customers;            /* Set of customers */
double AVAIL[MaxSuppliers];      /* Availability of products */
double DEMAND[MaxCustomers];     /* Demand by customers */
struct {
        int suppl;
        int custm;
        double value;
} COST[MaxArcs];                 /* Cost per supplier-customer pair */

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

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

void modtrans(XPRBprob prob)
{
 XPRBctr *av, *de, cobj;
 int s,c,a;
 XPRBvar *x;

/****VARIABLES****/
 x = (XPRBvar *)malloc(NArc * sizeof(XPRBvar));
 if(x==NULL) printf("Allocating memory for variables failed.");
 for(a=0; a<NArc; a++)
  x[a]=XPRBnewvar(prob,XPRB_PL,"x",0,XPRB_INFINITY);

/****OBJECTIVE****/
 cobj = XPRBnewctr(prob,"OBJ", XPRB_N);
 for(a=0; a<NArc; a++)
  XPRBaddterm(cobj, x[a], COST[a].value);
 XPRBsetobj(prob,cobj);          /* Select objective function */

/****CONSTRAINTS****/
    /**** Create all constraints in a single loop ****/
                                 /* Initialize the constraints */
 av = (XPRBctr *)malloc(NSuppl * sizeof(XPRBctr));
 if(av==NULL) printf("Not enough memory for AV constraints.");
 de = (XPRBctr *)malloc(NCustom * sizeof(XPRBctr));
 if(de==NULL) printf("Not enough memory for DE constraints.");
 for(s=0; s<NSuppl; s++)
  av[s]=XPRBnewctr(prob,"Avail", XPRB_L);
 for(c=0; c<NCustom; c++)
  de[c]=XPRBnewctr(prob,"Demand", XPRB_G);

    /* Add elements (coefficients) to constraints one-by-one */
 for(a=0; a<NArc; a++)
 {
  XPRBaddterm(av[COST[a].suppl],x[a],1);
  XPRBaddterm(de[COST[a].custm],x[a],1);
 }

    /* Terminate the constraint definition */
 for(s=0; s<NSuppl; s++)
  XPRBaddterm(av[s],NULL,AVAIL[s]);
 for(c=0; c<NCustom; c++)
  XPRBaddterm(de[c],NULL,DEMAND[c]);

/****SOLVING + OUTPUT****/
 XPRBexportprob(prob,XPRB_MPS,"trans");  /* Matrix output to MPS file */

 XPRBsetsense(prob,XPRB_MINIM);          /* Choose the sense of optimization */
 XPRBlpoptimize(prob,"");                /* Solve the LP-problem */
 printf("Objective: %g\n",XPRBgetobjval(prob));   /* Get objective value */

                     /* Print out the solution values for all arcs */
 for(a=0; a<NArc; a++)
 if(XPRBgetsol(x[a])>0)
  printf("%s (%g) -> %s (%g): %g\n",XPRBgetidxelname(Suppliers,COST[a].suppl),
    AVAIL[COST[a].suppl],
    XPRBgetidxelname(Customers,COST[a].custm),
    DEMAND[COST[a].custm], XPRBgetsol(x[a]));
}

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

    /**** Read data from files ****/
void readdata(XPRBprob prob)
{
 double value;
 FILE *datafile;
 char name[100], name2[100];

        /* Create supplier and customer index sets */
 Suppliers=XPRBnewidxset(prob,"suppl",MaxSuppliers);
 Customers=XPRBnewidxset(prob,"custom",MaxCustomers);

        /* Read the demand data file */
 datafile=fopen(DEMANDFILE,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T,g", name, &value) == 2)
  DEMAND[XPRBaddidxel(Customers,name)]=value;
 fclose(datafile);
 NCustom = XPRBgetidxsetsize(Customers);

        /* Read the supply data file */
 datafile=fopen(AVAILFILE,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T,g", name, &value) == 2)
  AVAIL[XPRBaddidxel(Suppliers,name)]=value;
 fclose(datafile);
 NSuppl = XPRBgetidxsetsize(Suppliers);

        /* Read the cost data file */
 NArc = 0;
 datafile=fopen(COSTFILE,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T,T,g", name,
        name2, &value) == 3)
 {
  COST[NArc].suppl = XPRBgetidxel(Suppliers, name);
  COST[NArc].custm = XPRBgetidxel(Customers, name2);
  if(COST[NArc].custm<0) printf("Cust(%s)\n",name2);
  if(COST[NArc].suppl<0) printf("Supp(%s)\n",name);
  COST[NArc++].value = value;
 }
 fclose(datafile);
 printf("C: %d  S: %d  A: %d\n",NCustom,NSuppl,NArc);
}

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

int main(int argc, char **argv)
{
 XPRBprob prob;

 prob=XPRBnewprob("Trans");    /* Initialize a new problem in BCL */
 readdata(prob);               /* Data input from file */
 modtrans(prob);               /* Formulate and solve the problem */

 return 0;
}

Back to examples browserPrevious exampleNext example