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





xbscenar.c

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

  file xbscenar.c
  ```````````````
  Different demand scenarios implemented with 
  multiple threads.

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

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

#define NSCENARIO 4              /* Number of demand scenarios */

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

#define DEMANDFILE XPRBDATAPATH "/trans/ex2dem"  
                                 /* Demand data file (name completed below) */
#define AVAILFILE XPRBDATAPATH "/trans/ex2avail.dat" 
                                 /* Supply data file */
#define COSTFILE XPRBDATAPATH "/trans/ex2cost.dat"   
                                 /* Cost data file */

struct Costarcs{
        int suppl;
        int custm;
        double value;
};

DWORD WINAPI trans(LPVOID param);
void XPRB_CC userprint(XPRBprob prob, void *file, const char *msg);   

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

/**********************/
/* Where things start */
/**********************/
int main(int argc,char *argv[])
{
 HANDLE tosolve[NSCENARIO];
 int i;

 XPRBinit();                     /* Initialize BCL */

 /* Start the building+solving in parallel */
 for(i=0;i<NSCENARIO;i++)
  tosolve[i]=CreateThread(NULL, 0, trans, (void *)(i+1),0 ,0);

 /* Wait for results */
 for(i=0;i<NSCENARIO;i++)
  WaitForSingleObject(tosolve[i], INFINITE);

 /* Clear up everything (not really required here since the program 
    terminates immediately afterwards) */
 XPRBfinish();
 return 0;
}

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

DWORD WINAPI trans(LPVOID param)
{
 double value;
 FILE *datafile, *outfile;
 char name[50], name1[100], name2[100];
 XPRBidxset Suppliers;            /* Set of suppliers */
 XPRBidxset Customers;            /* Set of customers */
 double AVAIL[MaxSuppliers];      /* Availability of products */
 double DEMAND[MaxCustomers];     /* Demand by customers */
 struct Costarcs COST[MaxArcs];   /* Cost per supplier-customer pair */
 int NSuppl=0,NCustom=0, NArc=0;  /* Actual numbers of suppliers, customers, 
                                     and arcs */
 XPRBctr *av, *de, cobj;
 int s,c,a;
 XPRBvar *x; 
 XPRBprob prob;

 sprintf(name, "Trans_%d", (int)param); 
 prob=XPRBnewprob(name);          /* Initialize a new problem in BCL */
 strcat(name, "_out.txt");
 outfile=fopen(name, "w");

 XPRBdefcbmsg(prob,userprint, outfile);  /* Redirect output to a file: comment
                                            this line out to get all display on
                                            screen */

        /* Create supplier and customer index sets */
 Suppliers=XPRBnewidxset(prob,"suppl",MaxSuppliers);
 Customers=XPRBnewidxset(prob,"custom",MaxCustomers);
 
        /* Read the demand data file for this problem */
 sprintf(name, "%s%d.dat", DEMANDFILE, (int)param);       
 datafile=fopen(name ,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T,g", name1, &value) == 2)
  DEMAND[XPRBaddidxel(Customers,name1)]=value;
 fclose(datafile);
 NCustom = XPRBgetidxsetsize(Customers);

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

        /* Read the cost data file */
 datafile=fopen(COSTFILE,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T,T,g", name1, name2,
        &value) == 3)
 {
  COST[NArc].suppl = XPRBgetidxel(Suppliers, name1);
  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",name1);
  COST[NArc++].value = value;
 }
 fclose(datafile);


/****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****/
 XPRBsetsense(prob,XPRB_MINIM);     /* Choose the sense of the optimization */
 XPRBlpoptimize(prob,"");           /* Solve the LP-problem */
 if(XPRBgetlpstat(prob) == XPRB_LP_OPTIMAL)
 {
  XPRBprintf(prob, "Problem %s Objective: %g\n", XPRBgetprobname(prob), 
             XPRBgetobjval(prob));
                                    /* Print objective value */

                     /* Print out the solution values for all arcs */
  for(a=0; a<NArc; a++)
  if(XPRBgetsol(x[a])>0)
   XPRBprintf(prob, "%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]));  
 }
 else
  XPRBprintf(prob, "Problem %s is infeasible\n", XPRBgetprobname(prob));

 free(x);
 free(av);
 free(de);
 XPRBdelprob(prob);

 fclose(outfile);
 
 return 0;
}

void XPRB_CC userprint(XPRBprob prob, void *file, const char *msg)
{
    /* Print output of each example into a different file */ 
  fprintf((FILE *)file, "%s", msg);
}

Back to examples browserPrevious exampleNext example