FICO Xpress Optimization Examples Repository
 FICO Optimization Community FICO Xpress Optimization Home

MT2 - Solving two problems in parallel in a thread-safe environment

Description
Parallel problem solving using multiple threads. Accessing Xpress Optimizer functions for a BCL problem.

Source Files
By clicking on a file name, a preview is opened at the bottom of this page.

xbmt2.c

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

file xbmt2.c

Implementing multiple threads with BCL and
Xpress-Optimizer.

Win32 version

(c) 2008-2024 Fair Isaac Corporation
author: Y. Colombani, 2001, rev. Mar. 2011
********************************************************/

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

/* Constants for contr1() */
#define District 6                    /* Number of districts */
#define Contract 10                   /* Number of contracts */
const int OUTPUT[] = {50, 40, 10, 20, 70, 50};  /* Max. output per district */
const int COST[]   = {50, 20, 25, 30, 45, 40};  /* Cost per district */
const int VOLUME[]   = {20, 10, 30, 15, 20, 30, 10, 50, 10, 20};
/* Volume of contracts */

/* Constants for portf() */
#define NVal 30                       /* Total number of values */
#define LIMIT 20                      /* Maximum number to be chosen */

#define QFILE XPRBDATAPATH "/portf/pfqcost.dat" /* Quadratic cost coeff.s */
#define BFILE XPRBDATAPATH "/portf/pfubds.dat"  /* Upper bounds on percentages */
#define CFILE XPRBDATAPATH "/portf/pflcost.dat" /* Linear cost coefficients */

/* The problems to solve */
DWORD WINAPI contr1(LPVOID param);
DWORD WINAPI portf(LPVOID param);

/**********************/
/* Where things start */
/**********************/
int main(int argc,char *argv[])
{
HANDLE tosolve1, tosolve2;
XPRBprob modcontr1, modfolio;

/* Initialize BCL and create two problems (separate initialization
of BCL only for clarity's sake, it could as well be left to
be done during the creation of the first problem) */
XPRBinit();
modcontr1=XPRBnewprob("Contr1");
modfolio=XPRBnewprob("Folio");

/* Start the building+solving in parallel */

/* Wait for results */
WaitForSingleObject(tosolve1, INFINITE);
WaitForSingleObject(tosolve2, INFINITE);

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

/*********************/
/* Problem 'contr1'  */
/*********************/
DWORD WINAPI contr1(LPVOID param)
{
int d,c;
XPRBprob bprob;
XPRSprob oprob;
XPRBctr c1,c2,cobj;
XPRBvar x[District][Contract];    /* Variables indicating whether a project
is chosen */
XPRBvar y[District][Contract];    /* Quantities allocated to contractors */
int i, ncol, len, stat, offset;
double *sol, val;
char *names;

bprob=(XPRBprob)param;

/**** VARIABLES ****/
for(d=0;d<District;d++)
for(c=0;c<Contract;c++)
{
x[d][c] = XPRBnewvar(bprob,XPRB_BV,XPRBnewname("x_d%d",d+1),0,1);
y[d][c] = XPRBnewvar(bprob,XPRB_SC,XPRBnewname("q_d%d",d+1),0,OUTPUT[d]);
XPRBsetlim(y[d][c],5);
}

/****OBJECTIVE****/
cobj = XPRBnewctr(bprob,"OBJ",XPRB_N);  /* Define objective: total cost */
for(d=0;d<District;d++)
for(c=0;c<Contract;c++)
XPRBsetobj(bprob,cobj);                 /* Set objective function */

/**** CONSTRAINTS ****/
for(c=0;c<Contract;c++)
{
c1=XPRBnewctr(bprob,"Size",XPRB_G); /* "Size": cover the required contract volume */
c2=XPRBnewctr(bprob,"Min",XPRB_G);  /* "Min": at least 2 districts per contract */
for(d=0;d<District;d++)
{
}
}

for(d=0;d<District;d++)        /* Do not exceed max. output of any district */
{
c1=XPRBnewctr(bprob,"Output",XPRB_L);
for(c=0;c<Contract;c++)
}

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++)
XPRBnewprec(bprob,"XY",x[d][c],0,y[d][c]);

/****SOLVING + OUTPUT****/
oprob=XPRBgetXPRSprob(bprob);
XPRSchgobjsense(oprob, XPRS_OBJ_MINIMIZE);  /* Set sense to minimization */
XPRSmipoptimize(oprob, "");                 /* Solve the MIP problem */

XPRSgetintattrib(oprob, XPRS_MIPSTATUS, &stat);  /* Get MIP status */
if((stat==XPRS_MIP_SOLUTION) || (stat==XPRS_MIP_OPTIMAL))
/* Test whether an integer solution was found */
{
XPRSgetdblattrib(oprob, XPRS_MIPOBJVAL, &val);
printf("Problem %s Objective: %g\n", XPRBgetprobname(bprob), val);
XPRSgetintattrib(oprob, XPRS_ORIGINALCOLS, &ncol);
sol = (double *)malloc(ncol * sizeof(double));
XPRSgetmipsol(oprob, sol, NULL);   /* Get the primal solution values */
XPRSgetnamelist(oprob, 2, NULL, 0, &len, 0, ncol-1);
/* Get number of bytes required for retrieving names */
names = (char *)malloc(len*sizeof(char));
XPRSgetnamelist(oprob, 2, names, len, NULL, 0, ncol-1);
/* Get the variable names */
offset=0;
for(i=0; i<ncol; i++) {            /* Print out the solution */
if(sol[i]!=0)
printf("%s: %g, ", names+offset, sol[i]);
offset += strlen(names+offset)+1;
}
printf("\n");
free(sol);
free(names);
}

return 0;
}

/**************************/
/* The portfolio example  */
/**************************/
DWORD WINAPI portf(LPVOID param)
{
/**** DATA ****/
double Cost[NVal];                   /* Coeff. of lin. part of the obj. */
double QCost[NVal][NVal];            /* Coeff. of quad. part of the obj. */
double UBnd[NVal];                   /* Upper bound values */
double value;
FILE *datafile;

int i,j;
XPRBctr cobj, c;
XPRBvar x[NVal];                     /* Amount of a value taken into
the portfolio */
XPRBvar y[NVal];                     /* 1 if value i is chosen, else 0 */
XPRBprob bprob;

bprob=(XPRBprob)param;

/**** Read data from files ****/
memset(QCost,0,NVal*NVal*sizeof(double));      /* Initialize Q to 0 */
datafile=fopen(QFILE,"r");
while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "i,i,g", &i, &j,
&value) == 3)
QCost[i-1][j-1]=value;
fclose(datafile);

/* Read the linear cost data file */
datafile=fopen(CFILE,"r");
while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "i,g", &i, &value) == 2)
Cost[i-1]=value;
fclose(datafile);

/* Read the bounds data file */
datafile=fopen(BFILE,"r");
while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "i,g", &i, &value) == 2)
UBnd[i-1]=value;
fclose(datafile);

/**** VARIABLES ****/
for(i=0;i<NVal;i++)
{
x[i] = XPRBnewvar(bprob,XPRB_PL, XPRBnewname("x_%d",i+1), 0, UBnd[i]);
y[i] = XPRBnewvar(bprob,XPRB_BV, XPRBnewname("y_%d",i+1), 0, 1);
}

/****OBJECTIVE****/
cobj = XPRBnewctr(bprob,"OBJ",XPRB_N); /* Define objective: total cost */
for(i=0;i<NVal;i++)

for(i=0;i<NVal;i++)                  /* Define quadratic part of the obj. */
{
for(j=i+1;j<NVal;j++)
}
XPRBsetobj(bprob,cobj);              /* Set objective function */

/**** CONSTRAINTS ****/
c = XPRBnewctr(bprob,"C1",XPRB_E);   /* Amounts of values chosen must

for(i=0;i<NVal;i++)                  /* Upper limits */
{
c = XPRBnewctr(bprob,"UL",XPRB_L);
}

c = XPRBnewctr(bprob,"Card", XPRB_L);   /* Limit on total number of values */

/****SOLVING + OUTPUT****/
/* XPRBprintprob(bprob); */           /* Print out the problem definition */
XPRBexportprob(bprob,XPRB_MPS,"Portf"); /* Output matrix in MPS format */
XPRBexportprob(bprob,XPRB_LP,"Portf");  /* Output matrix in LP format */

XPRBsetsense(bprob,XPRB_MINIM);      /* Choose the sense of the optimization */