Initializing help system before first use

Folio - Examples from 'Getting Started'


Type: Portfolio optimization
Rating: 3 (intermediate)
Description: Different versions of a portfolio optimization problem.
Basic modelling and solving tasks:
  • modeling and solving a small LP problem (foliolp, using variable arrays: folioarr)
  • performing explicit initialization (folioinit*)
  • data input from file, index sets (foliodata, requires foliocpplp.dat)
  • modeling and solving a small MIP problem with binary variables (foliomip1)
  • modeling and solving a small MIP problem with semi-continuous variables (foliomip2)
  • modeling and solving QP and MIQP problems (folioqp, requires foliocppqp.dat)
  • modeling and solving QCQP problems (folioqc, requires foliocppqp.dat)
  • heuristic solution of a MIP problem (folioheur)
Advanced modeling and solving tasks:
  • enlarged version of the basic MIP model (foliomip3 with include file readfoliodata.c_, to be used with data sets folio5.cdat, folio10.cdat)
  • defining an integer solution callback (foliocb)
  • using the MIP solution pool (foliosolpool)
  • using the solution enumerator (folioenumsol)
  • handling infeasibility through deviation variables (folioinfeas)
  • retrieving IIS (folioiis, foliomiis)
  • using the built-in infeasibility repair functionality (foliorep)
File(s): foliolp.c, folioarr.c, folioinit.c, folioinit2.c, foliodata.c, foliomip1.c, foliomip2.c, folioqp.c, folioqc.c, folioheur.c, foliomip3.c, readfoliodata.c_, foliocb.c, foliosolpool.c, folioenumsol.c, folioinfeas.c, folioiis.c, foliomiis.c, foliorep.c
Data file(s): foliocpplp.dat, foliocppqp.dat, folio5.cdat, folio10.cdat

foliolp.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file foliolp.c
  ``````````````
  Modeling a small LP problem
  to perform portfolio optimization.

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

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

#define NSHARES 10                   /* Number of shares */
#define NRISK 5                      /* Number of high-risk shares */
#define NNA 4                        /* Number of North-American shares */

double RET[] = {5,17,26,12,8,9,7,6,31,21};  /* Estimated return in investment */
int RISK[] = {1,2,3,8,9};            /* High-risk values among shares */
int NA[] = {0,1,2,3};                /* Shares issued in N.-America */

int main(int argc, char **argv)
{
 int s;
 XPRBprob prob;
 XPRBctr Risk,Na,Return,Cap;
 XPRBvar frac[NSHARES];              /* Fraction of capital used per share */
 char *LPSTATUS[] = {"not loaded", "optimal", "infeasible",
          "worse than cutoff", "unfinished", "unbounded", "cutoff in dual",
	  "unsolved", "nonconvex"};

 prob = XPRBnewprob("FolioLP");      /* Initialize a new problem in BCL */

/* Create the decision variables */
 for(s=0;s<NSHARES;s++)
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, XPRB_INFINITY);
                   /* (prob, XPRB_PL, "frac", 0, 0.3); */

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);            /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, 1.0/3);

/* Minimum amount of North-American values */
 Na = XPRBnewctr(prob, "NA", XPRB_G);
 for(s=0;s<NNA;s++) XPRBaddterm(Na, frac[NA[s]], 1);
 XPRBaddterm(Na, NULL, 0.5);

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Upper bounds on the investment per share */
 for(s=0;s<NSHARES;s++) XPRBsetub(frac[s], 0.3);

/* Export matrix to a file */
/* XPRBexportprob(prob, XPRB_MPS, "Folio");
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBexportprob(prob, XPRB_LP, "Folio");
*/

/* Disable all BCL and Optimizer message printing, except error messages */
/* XPRBsetmsglevel(prob, 1); */

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBlpoptimize(prob, "");

 printf("Problem status: %s\n", LPSTATUS[XPRBgetlpstat(prob)]);

/* Solution printing */
 printf("Total return: %g\n", XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  printf(" %d : %g%%\n", s, XPRBgetsol(frac[s])*100);

 return 0;
}

folioarr.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file folioarr.c
  ```````````````
  Modeling a small LP problem
  to perform portfolio optimization.
  -- Array-based formulation --

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

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

#define NSHARES 10                   /* Number of shares */
#define NRISK 5                      /* Number of high-risk shares */
#define NNA 4                        /* Number of North-American shares */

double RET[] = {5,17,26,12,8,9,7,6,31,21};  /* Estimated return in investment */
int RISK[] = {1,2,3,8,9};            /* High-risk values among shares */
int NA[] = {0,1,2,3};                /* Shares issued in N.-America */

int main(int argc, char **argv)
{
 int s;
 XPRBprob prob;
 XPRBctr Risk,Na,Return,Cap;
 XPRBarrvar frac;                    /* Fraction of capital used per share */

 prob = XPRBnewprob("FolioLP");      /* Initialize a new problem in BCL */

/* Create the decision variables */
 frac = XPRBnewarrvar(prob, NSHARES, XPRB_PL, "frac", 0, XPRB_INFINITY);

/* Objective: total return */
 Return = XPRBnewarrsum(prob, "Return", frac, RET, XPRB_N, 0);
 XPRBsetobj(prob,Return);            /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, 1.0/3);

/* Minimum amount of North-American values */
 Na = XPRBnewctr(prob, "NA", XPRB_G);
 for(s=0;s<NNA;s++) XPRBaddterm(Na, frac[NA[s]], 1);
 XPRBaddterm(Na, NULL, 0.5);

/* Spend all the capital */
 Cap = XPRBnewsum(prob, "Cap", frac, XPRB_E, 1);

/* Upper bounds on the investment per share */
 for(s=0;s<NSHARES;s++) XPRBsetub(frac[s], 0.3);

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBlpoptimize(prob, "");

/* Solution printing */
 if(XPRBgetlpstat(prob)==XPRB_LP_OPTIMAL)
 {
  printf("Total return: %g\n", XPRBgetobjval(prob));
  for(s=0;s<NSHARES;s++)
   printf(" %d : %g%%\n", s, XPRBgetsol(frac[s])*100);
 }

 return 0;
}

folioinit.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file folioinit.c
  ````````````````
  Modeling a small LP problem
  to perform portfolio optimization.
  -- Explicit initialization. --

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

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

#define NSHARES 10                   /* Number of shares */
#define NRISK 5                      /* Number of high-risk shares */
#define NNA 4                        /* Number of North-American shares */

double RET[] = {5,17,26,12,8,9,7,6,31,21};  /* Estimated return in investment */
int RISK[] = {1,2,3,8,9};            /* High-risk values among shares */
int NA[] = {0,1,2,3};                /* Shares issued in N.-America */

void solveprob(void)
{
 int s;
 XPRBprob prob;
 XPRBctr Risk,Na,Return,Cap;
 XPRBvar frac[NSHARES];              /* Fraction of capital used per share */
 char *LPSTATUS[] = {"not loaded", "optimal", "infeasible",
          "worse than cutoff", "unfinished", "unbounded", "cutoff in dual",
	  "unsolved", "nonconvex"};

 prob = XPRBnewprob("FolioLP");      /* Initialize a new problem in BCL */

/* Create the decision variables */
 for(s=0;s<NSHARES;s++)
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, XPRB_INFINITY);

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);            /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, 1.0/3);

/* Minimum amount of North-American values */
 Na = XPRBnewctr(prob, "NA", XPRB_G);
 for(s=0;s<NNA;s++) XPRBaddterm(Na, frac[NA[s]], 1);
 XPRBaddterm(Na, NULL, 0.5);

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Upper bounds on the investment per share */
 for(s=0;s<NSHARES;s++) XPRBsetub(frac[s], 0.3);

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBlpoptimize(prob, "");

 printf("Problem status: %s\n", LPSTATUS[XPRBgetlpstat(prob)]);

/* Solution printing */
 printf("Total return: %g\n", XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  printf(" %d : %g%%\n", s, XPRBgetsol(frac[s])*100);
}

int main(int argc, char **argv)
{
 if(XPRBinit() != 0)
 {
   printf("Initialization failed.\n");
   return 1;
 }
 solveprob();
 return 0;
}

folioinit2.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file folioinit.c
  ````````````````
  Modeling a small LP problem
  to perform portfolio optimization.
  -- Explicit initialization. --

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

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

#define NSHARES 10                   /* Number of shares */
#define NRISK 5                      /* Number of high-risk shares */
#define NNA 4                        /* Number of North-American shares */

double RET[] = {5,17,26,12,8,9,7,6,31,21};  /* Estimated return in investment */
int RISK[] = {1,2,3,8,9};            /* High-risk values among shares */
int NA[] = {0,1,2,3};                /* Shares issued in N.-America */

int main(int argc, char **argv)
{
 int s;
 XPRBprob prob;
 XPRBctr Risk,Na,Return,Cap;
 XPRBvar frac[NSHARES];              /* Fraction of capital used per share */
 char *LPSTATUS[] = {"not loaded", "optimal", "infeasible",
          "worse than cutoff", "unfinished", "unbounded", "cutoff in dual",
	  "unsolved", "nonconvex"};

 if(XPRBinit() != 0)
 {
   printf("Initialization failed.\n");
   return 1;
 }

 prob = XPRBnewprob("FolioLP");      /* Initialize a new problem in BCL */

/* Create the decision variables */
 for(s=0;s<NSHARES;s++)
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, XPRB_INFINITY);

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);            /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, 1.0/3);

/* Minimum amount of North-American values */
 Na = XPRBnewctr(prob, "NA", XPRB_G);
 for(s=0;s<NNA;s++) XPRBaddterm(Na, frac[NA[s]], 1);
 XPRBaddterm(Na, NULL, 0.5);

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Upper bounds on the investment per share */
 for(s=0;s<NSHARES;s++) XPRBsetub(frac[s], 0.3);

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBlpoptimize(prob, "");

 printf("Problem status: %s\n", LPSTATUS[XPRBgetlpstat(prob)]);

/* Solution printing */
 printf("Total return: %g\n", XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  printf(" %d : %g%%\n", s, XPRBgetsol(frac[s])*100);

 return 0;
}

foliodata.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file foliodata.c
  ````````````````
  Modeling a small LP problem
  to perform portfolio optimization.
  -- Data input from file --

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

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

#define DATAFILE XPRBDATAPATH "/GS/foliocpplp.dat"

#define NSHARES 10                   /* Number of shares */
#define NRISK 5                      /* Number of high-risk shares */
#define NNA 4                        /* Number of North-American shares */

double RET[NSHARES];                 /* Estimated return in investment */
char RISK[][100] = {"hardware", "theater", "telecom", "software",
                    "electronics"};  /* High-risk values among shares */
char NA[][100] = {"treasury", "hardware", "theater", "telecom"};
                                     /* Shares issued in N.-America */

XPRBidxset SHARES;                   /* Set of shares */

XPRBprob prob;

void readData(void)
{
 double value;
 int s;
 FILE *datafile;
 char name[100];
                                     /* Create the `SHARES' index set */
 SHARES = XPRBnewidxset(prob, "Shares", NSHARES);

/* Read `RET' data from file */
 datafile = fopen(DATAFILE,"r");
 for(s=0;s<NSHARES;s++)
 {
  XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T g", name, &value);
  RET[XPRBaddidxel(SHARES, name)] = value;
 }
 fclose(datafile);

 XPRBprintidxset(SHARES);            /* Print out the set contents */
}

int main(int argc, char **argv)
{
 int s;
 XPRBctr Risk,Na,Return,Cap;
 XPRBvar frac[NSHARES];              /* Fraction of capital used per share */

 prob = XPRBnewprob("FolioLP");      /* Initialize a new problem in BCL */

/* Read data from file */
 readData();

/* Create the decision variables */
 for(s=0;s<NSHARES;s++)
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, XPRB_INFINITY);

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);               /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[XPRBgetidxel(SHARES,RISK[s])], 1);
 XPRBaddterm(Risk, NULL, 1.0/3);

/* Minimum amount of North-American values */
 Na = XPRBnewctr(prob, "NA", XPRB_G);
 for(s=0;s<NNA;s++) XPRBaddterm(Na, frac[XPRBgetidxel(SHARES,NA[s])], 1);
 XPRBaddterm(Na, NULL, 0.5);

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Upper bounds on the investment per share */
 for(s=0;s<NSHARES;s++) XPRBsetub(frac[s], 0.3);

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBlpoptimize(prob, "");

/* Solution printing */
 printf("Total return: %g\n", XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  printf(" %s : %g%%\n", XPRBgetidxelname(SHARES,s), XPRBgetsol(frac[s])*100);

 return 0;
}

foliomip1.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file foliomip1.c
  ````````````````
  Modeling a small MIP problem
  to perform portfolio optimization.
   -- Limiting the total number of assets --

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

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

#define MAXNUM 4                   /* Max. number of different assets */

#define NSHARES 10                 /* Number of shares */
#define NRISK 5                    /* Number of high-risk shares */
#define NNA 4                      /* Number of North-American shares */

double RET[] = {5,17,26,12,8,9,7,6,31,21};  /* Estimated return in investment */
int RISK[] = {1,2,3,8,9};          /* High-risk values among shares */
int NA[] = {0,1,2,3};              /* Shares issued in N.-America */

int main(int argc, char **argv)
{
 int s;
 XPRBprob prob;
 XPRBctr Risk,Na,Return,Cap,Num;
 XPRBvar frac[NSHARES];            /* Fraction of capital used per share */
 XPRBvar buy[NSHARES];             /* 1 if asset is in portfolio, 0 otherwise */
 char *MIPSTATUS[] = {"not loaded", "not optimized", "LP optimized",
                      "unfinished (no solution)",
                      "unfinished (solution found)", "infeasible", "optimal",
                      "unbounded"};

 prob = XPRBnewprob("FolioMIP1");  /* Initialize a new problem in BCL */

/* Create the decision variables (including upper bounds for `frac') */
 for(s=0;s<NSHARES;s++)
 {
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, 0.3);
  buy[s] = XPRBnewvar(prob, XPRB_BV, "buy", 0, 1);
 }

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);          /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, 1.0/3);

/* Minimum amount of North-American values */
 Na = XPRBnewctr(prob, "NA", XPRB_G);
 for(s=0;s<NNA;s++) XPRBaddterm(Na, frac[NA[s]], 1);
 XPRBaddterm(Na, NULL, 0.5);

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Limit the total number of assets */
 Num = XPRBnewctr(prob, "Num", XPRB_L);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Num, buy[s], 1);
 XPRBaddterm(Num, NULL, MAXNUM);

/* Linking the variables */
 for(s=0;s<NSHARES;s++) XPRBnewprec(prob, "Link", frac[s], 0, buy[s]);

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBmipoptimize(prob, "");

 printf("Problem status: %s\n", MIPSTATUS[XPRBgetmipstat(prob)]);

/* Solution printing */
 printf("Total return: %g\n", XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  printf(" %d : %g%% (%g)\n", s, XPRBgetsol(frac[s])*100, XPRBgetsol(buy[s]));

 return 0;
}

foliomip2.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file foliomip2.c
  ````````````````
  Modeling a small MIP problem
  to perform portfolio optimization.
  -- Imposing a minimum investment per share --

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

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

#define NSHARES 10                 /* Number of shares */
#define NRISK 5                    /* Number of high-risk shares */
#define NNA 4                      /* Number of North-American shares */

double RET[] = {5,17,26,12,8,9,7,6,31,21};  /* Estimated return in investment */
int RISK[] = {1,2,3,8,9};          /* High-risk values among shares */
int NA[] = {0,1,2,3};              /* Shares issued in N.-America */

int main(int argc, char **argv)
{
 int s;
 XPRBprob prob;
 XPRBctr Risk,Na,Return,Cap;
 XPRBvar frac[NSHARES];            /* Fraction of capital used per share */

 prob = XPRBnewprob("FolioSC");    /* Initialize a new problem in BCL */

/* Create the decision variables */
 for(s=0;s<NSHARES;s++)
 {
  frac[s] = XPRBnewvar(prob, XPRB_SC, "frac", 0, 0.3);
  XPRBsetlim(frac[s], 0.1);
 }

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);          /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, 1.0/3);

/* Minimum amount of North-American values */
 Na = XPRBnewctr(prob, "NA", XPRB_G);
 for(s=0;s<NNA;s++) XPRBaddterm(Na, frac[NA[s]], 1);
 XPRBaddterm(Na, NULL, 0.5);

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBmipoptimize(prob, "");

/* Solution printing */
 printf("Total return: %g\n", XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  printf(" %d : %g%%\n", s, XPRBgetsol(frac[s])*100);

 return 0;
}

folioqp.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file folioqp.c
  ``````````````
  Modeling a small QP problem
  to perform portfolio optimization.
   -- 1. QP: minimize variance
      2. MIQP: limited number of assets ---

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

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

#define DATAFILE XPRBDATAPATH "/GS/foliocppqp.dat"

#define TARGET 9                   /* Target yield */
#define MAXNUM 4                   /* Max. number of different assets */

#define NSHARES 10                 /* Number of shares */
#define NNA 4                      /* Number of North-American shares */

double RET[] = {5,17,26,12,8,9,7,6,31,21};  /* Estimated return in investment */
int NA[] = {0,1,2,3};              /* Shares issued in N.-America */
double VAR[NSHARES][NSHARES];      /* Variance/covariance matrix of
                                      estimated returns */

int main(int argc, char **argv)
{
 int s,t;
 XPRBprob prob;
 XPRBctr Variance,Na,Return,Cap,Num;
 XPRBvar frac[NSHARES];            /* Fraction of capital used per share */
 XPRBvar buy[NSHARES];             /* 1 if asset is in portfolio, 0 otherwise */
 FILE *datafile;

 prob = XPRBnewprob("FolioQP");    /* Initialize a new problem in BCL */

/* Read `VAR' data from file */
 datafile=fopen(DATAFILE,"r");
 for(s=0;s<NSHARES;s++)
  XPRBreadarrlinecb(XPRB_FGETS, datafile,200,"g ",VAR[s],NSHARES);
 fclose(datafile);

/***** First problem: unlimited number of assets *****/

/* Create the decision variables */
 for(s=0;s<NSHARES;s++)
  frac[s] = XPRBnewvar(prob, XPRB_PL, XPRBnewname("frac(%d)",s+1), 0, 0.3);

/* Objective: mean variance */
 Variance = XPRBnewctr(prob, "Variance", XPRB_N);
 for(s=0;s<NSHARES;s++)
  for(t=0;t<NSHARES;t++) XPRBaddqterm(Variance, frac[s], frac[t], VAR[s][t]);
 XPRBsetobj(prob, Variance);

/* Minimum amount of North-American values */
 Na = XPRBnewctr(prob, "NA", XPRB_G);
 for(s=0;s<NNA;s++) XPRBaddterm(Na, frac[NA[s]], 1);
 XPRBaddterm(Na, NULL, 0.5);

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Target yield */
 Return = XPRBnewctr(prob, "Return", XPRB_G);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBaddterm(Return, NULL, TARGET);

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MINIM);
 XPRBlpoptimize(prob, "");

/* Solution printing */
 printf("With a target of %d minimum variance is %g\n", TARGET,
        XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  printf(" %d : %g%%\n", s, XPRBgetsol(frac[s])*100);

/***** Second problem: limit total number of assets *****/

/* Create the decision variables */
 for(s=0;s<NSHARES;s++)
  buy[s] = XPRBnewvar(prob, XPRB_BV, XPRBnewname("buy(%d)",s+1), 0, 1);

/* Limit the total number of assets */
 Num = XPRBnewctr(prob, "Num", XPRB_L);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Num, buy[s], 1);
 XPRBaddterm(Num, NULL, MAXNUM);

/* Linking the variables */
 for(s=0;s<NSHARES;s++) XPRBnewprec(prob, "Link", frac[s], 0, buy[s]);

/* Solve the problem */
 XPRBmipoptimize(prob, "");

/* Solution printing */
 printf("With a target of %d and at most %d assets, minimum variance is %g\n",
        TARGET, MAXNUM, XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  printf(" %d : %g%% (%g)\n", s, XPRBgetsol(frac[s])*100, XPRBgetsol(buy[s]));

 return 0;
}


folioqc.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file folioqc.c
  ``````````````
  Modeling a small QCQP problem
  to perform portfolio optimization.
  -- Maximize return with limit on variance ---

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

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

#define DATAFILE XPRBDATAPATH "/GS/foliocppqp.dat"

#define MAXVAR 0.55                /* Max. allowed variance */

#define NSHARES 10                 /* Number of shares */
#define NNA 4                      /* Number of North-American shares */

double RET[] = {5,17,26,12,8,9,7,6,31,21};  /* Estimated return in investment */
int NA[] = {0,1,2,3};              /* Shares issued in N.-America */
double VAR[NSHARES][NSHARES];      /* Variance/covariance matrix of
                                      estimated returns */

int main(int argc, char **argv)
{
 int s,t;
 XPRBprob prob;
 XPRBctr Variance,Na,Return,Cap;
 XPRBvar frac[NSHARES];            /* Fraction of capital used per share */
 FILE *datafile;

 prob = XPRBnewprob("FolioQP");    /* Initialize a new problem in BCL */

/* Read `VAR' data from file */
 datafile=fopen(DATAFILE,"r");
 for(s=0;s<NSHARES;s++)
  XPRBreadarrlinecb(XPRB_FGETS, datafile, 200, "g ", VAR[s], NSHARES);
 fclose(datafile);

/* Create the decision variables */
 for(s=0;s<NSHARES;s++)
  frac[s] = XPRBnewvar(prob, XPRB_PL, XPRBnewname("frac(%d)",s+1), 0, 0.3);

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob, Return);

/* Minimum amount of North-American values */
 Na = XPRBnewctr(prob, "NA", XPRB_G);
 for(s=0;s<NNA;s++) XPRBaddterm(Na, frac[NA[s]], 1);
 XPRBaddterm(Na, NULL, 0.5);

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Limit variance */
 Variance = XPRBnewctr(prob, "Variance", XPRB_L);
 for(s=0;s<NSHARES;s++)
  for(t=0;t<NSHARES;t++) XPRBaddqterm(Variance, frac[s], frac[t], VAR[s][t]);
 XPRBaddterm(Variance, NULL, MAXVAR);

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBlpoptimize(prob, "");

/* Solution printing */
 printf("With a max. variance of %g total return is %g\n", MAXVAR,
        XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  printf(" %d : %g%%\n", s, XPRBgetsol(frac[s])*100);

 return 0;
}


folioheur.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file folioheur.c
  ````````````````
  Modeling a small MIP problem
  to perform portfolio optimization.
   -- Heuristic solution --

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

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

#define MAXNUM 4                  /* Max. number of different assets */

#define NSHARES 10                /* Number of shares */
#define NRISK 5                   /* Number of high-risk shares */
#define NNA 4                     /* Number of North-American shares */

void solveHeur(void);

double RET[] = {5,17,26,12,8,9,7,6,31,21};  /* Estimated return in investment */
int RISK[] = {1,2,3,8,9};         /* High-risk values among shares */
int NA[] = {0,1,2,3};             /* Shares issued in N.-America */

XPRBprob prob;
XPRBvar frac[NSHARES];            /* Fraction of capital used per share */
XPRBvar buy[NSHARES];             /* 1 if asset is in portfolio, 0 otherwise */

int main(int argc, char **argv)
{
 int s;
 XPRBctr Risk,Na,Return,Cap,Num;

 prob = XPRBnewprob("FolioMIPHeur");  /* Initialize a new problem in BCL */

/* Create the decision variables (including upper bounds for `frac') */
 for(s=0;s<NSHARES;s++)
 {
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, 0.3);
  buy[s] = XPRBnewvar(prob, XPRB_BV, "buy", 0, 1);
 }

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);               /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, 1.0/3);

/* Minimum amount of North-American values */
 Na = XPRBnewctr(prob, "NA", XPRB_G);
 for(s=0;s<NNA;s++) XPRBaddterm(Na, frac[NA[s]], 1);
 XPRBaddterm(Na, NULL, 0.5);

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Limit the total number of assets */
 Num = XPRBnewctr(prob, "Num", XPRB_L);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Num, buy[s], 1);
 XPRBaddterm(Num, NULL, MAXNUM);

/* Linking the variables */
 for(s=0;s<NSHARES;s++) XPRBnewprec(prob, "Link", frac[s], 0, buy[s]);

/* Solve problem heuristically */
 XPRBsetsense(prob, XPRB_MAXIM);
 solveHeur();

/* Solve the problem */
 XPRBmipoptimize(prob, "");

/* Solution printing */
 if(XPRBgetmipstat(prob)==XPRB_MIP_SOLUTION ||
    XPRBgetmipstat(prob)==XPRB_MIP_OPTIMAL)
 {
  printf("Exact solution: Total return: %g\n", XPRBgetobjval(prob));
  for(s=0;s<NSHARES;s++)
   printf(" %d : %g%%\n", s, XPRBgetsol(frac[s])*100);
 }
 else
  printf("Heuristic solution is optimal.\n");

 return 0;
}

void solveHeur(void)
{
 XPRBbasis basis;
 int s, ifgsol;
 double solval, fsol[NSHARES],TOL;

 XPRSsetintcontrol(XPRBgetXPRSprob(prob), XPRS_CUTSTRATEGY, 0);
                                   /* Disable automatic cuts */
 XPRSsetintcontrol(XPRBgetXPRSprob(prob), XPRS_PRESOLVE, 0);
                                   /* Switch presolve off */
 XPRSgetdblcontrol(XPRBgetXPRSprob(prob), XPRS_FEASTOL, &TOL);
                                   /* Get feasibility tolerance */

 XPRBmipoptimize(prob, "l");       /* Solve the LP-problem */
 basis=XPRBsavebasis(prob);        /* Save the current basis */

/* Fix all variables `buy' for which `frac' is at 0 or at a relatively
   large value */
 for(s=0;s<NSHARES;s++)
 {
  fsol[s]=XPRBgetsol(frac[s]);     /* Get the solution values of `frac' */
  if(fsol[s] < TOL)  XPRBsetub(buy[s], 0);
  else if(fsol[s] > 0.2-TOL)  XPRBsetlb(buy[s], 1);
 }

 XPRBmipoptimize(prob, "c");       /* Continue solving the MIP-problem */
 ifgsol=0;
 if(XPRBgetmipstat(prob)==XPRB_MIP_SOLUTION ||
    XPRBgetmipstat(prob)==XPRB_MIP_OPTIMAL)
 {                                 /* If an integer feas. solution was found */
  ifgsol=1;
  solval=XPRBgetobjval(prob);      /* Get the value of the best solution */
  printf("Heuristic solution: Total return: %g\n", XPRBgetobjval(prob));
  for(s=0;s<NSHARES;s++)
   printf(" %d : %g%%\n", s, XPRBgetsol(frac[s])*100);
 }

 XPRSpostsolve(XPRBgetXPRSprob(prob));  /* Re-initialize the global search */

/* Reset variables to their original bounds */
 for(s=0;s<NSHARES;s++)
  if((fsol[s] < TOL) || (fsol[s] > 0.2-TOL))
  {
   XPRBsetlb(buy[s], 0);
   XPRBsetub(buy[s], 1);
  }

 XPRBloadbasis(basis);      /* Load the saved basis: bound changes are
                               immediately passed on from BCL to the
                               Optimizer if the problem has not been modified
                               in any other way, so that there is no need to
                               reload the matrix */
 XPRBdelbasis(basis);       /* No need to store the saved basis any longer */
 if(ifgsol==1)
  XPRSsetdblcontrol(XPRBgetXPRSprob(prob), XPRS_MIPABSCUTOFF, solval+TOL);
                            /* Set the cutoff to the best known solution */
}

foliomip3.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file foliomip3.c
  ````````````````
  Modeling a MIP problem
  to perform portfolio optimization.
   -- Extending the problem with constraints on
      the geographical and sectorial distributions --
   -- Working with a larger data set --

  (c) 2009 Fair Isaac Corporation
      author: S.Heipcke, May 2009, rev. Mar. 2011
********************************************************/

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


#define MAXNUM 7                   /* Max. number of different assets */
#define MAXRISK 1.0/3              /* Max. investment into high-risk values */
#define MINREG 0.2                 /* Min. investment per geogr. region */
#define MAXREG 0.5                 /* Max. investment per geogr. region */
#define MAXSEC 0.25                /* Max. investment per ind. sector */
#define MAXVAL 0.2                 /* Max. investment per share */
#define MINVAL 0.1                 /* Min. investment per share */

#define DATAFILE "folio10.cdat"    /* File with problem data */
#define MAXENTRIES 10000


int NSHARES;                       /* Number of shares */
int NRISK;                         /* Number of high-risk shares */
int NREGIONS;                      /* Number of geographical regions */
int NTYPES;                        /* Number of share types */

double *RET;                       /* Estimated return in investment */
int *RISK;                         /* High-risk values among shares */
char **LOC;                        /* Geogr. region of shares */
char **SEC;                        /* Industry sector of shares */

char **SHARES_n;
char **REGIONS_n;
char **TYPES_n;

#include "readfoliodata.c_"

int main(int argc, char **argv)
{
 int s,r,t;
 XPRBprob prob;
 XPRBctr Risk,Return,Cap,Num;
 XPRBctr *MinReg, *MaxReg, *LimSec, LinkL, LinkU;
 XPRBvar *frac;                   /* Fraction of capital used per share */
 XPRBvar *buy;                    /* 1 if asset is in portfolio, 0 otherwise */
 char *MIPSTATUS[] = {"not loaded", "not optimized", "LP optimized",
                      "unfinished (no solution)",
                      "unfinished (solution found)", "infeasible", "optimal",
                      "unbounded"};

 readdata(DATAFILE);               /* Data input from file */

 prob = XPRBnewprob("FolioMIP3");  /* Initialize a new problem in BCL */

/* Create the decision variables (including upper bounds for `frac') */
 frac = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 buy = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 for(s=0;s<NSHARES;s++)
 {
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, MAXVAL);
  buy[s] = XPRBnewvar(prob, XPRB_BV, "buy", 0, 1);
 }

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);          /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, MAXRISK);

/* Limits on geographical distribution */
 MinReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 MaxReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 for(r=0;r<NREGIONS;r++)
 {
  MinReg[r] = XPRBnewctr(prob, "MinReg", XPRB_G);
  MaxReg[r] = XPRBnewctr(prob, "MaxReg", XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(LOC[r][s]>0)
   {
    XPRBaddterm(MinReg[r], frac[s], 1);
    XPRBaddterm(MaxReg[r], frac[s], 1);
   }
  XPRBaddterm(MinReg[r], NULL, MINREG);
  XPRBaddterm(MaxReg[r], NULL, MAXREG);
 }

/* Diversification across industry sectors */
 LimSec = (XPRBctr*)malloc(NTYPES*sizeof(XPRBctr));
 for(t=0;t<NTYPES;t++)
 {
  LimSec[t] = XPRBnewctr(prob, "LimSec", XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(SEC[t][s]>0) XPRBaddterm(LimSec[t], frac[s], 1);
  XPRBaddterm(LimSec[t], NULL, MAXSEC);
 }

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Limit the total number of assets */
 Num = XPRBnewctr(prob, "Num", XPRB_L);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Num, buy[s], 1);
 XPRBaddterm(Num, NULL, MAXNUM);

/* Linking the variables */
 for(s=0;s<NSHARES;s++)
 {
  LinkU = XPRBnewctr(prob, "LinkU", XPRB_L);
  XPRBaddterm(LinkU, frac[s], 1);
  XPRBaddterm(LinkU, buy[s], -MAXVAL);
  LinkL = XPRBnewctr(prob, "LinkL", XPRB_G);
  XPRBaddterm(LinkL, frac[s], 1);
  XPRBaddterm(LinkL, buy[s], -MINVAL);
 }

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBmipoptimize(prob, "");

 printf("Problem status: %s\n", MIPSTATUS[XPRBgetmipstat(prob)]);

/* Solution printing */
 printf("Total return: %g\n", XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  if(XPRBgetsol(buy[s])>0.5)
   printf("  %d : %g%% (%g)\n", s, XPRBgetsol(frac[s])*100, XPRBgetsol(buy[s]));

 return 0;
}

readfoliodata.c_
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file readfoliodata.c_
  `````````````````````
  Include file reading data for model foliomip3 
  from a text file.

  (c) 2009 Fair Isaac Corporation
      author: Y.Colombani, May 2009
********************************************************/


/****************************************************/
/* Skip empty lines & comments and find next record */
/****************************************************/
int nextrec(FILE *f,char *rec)
{
 int c;

 do
 {
  c=fgetc(f);
  if(c==EOF) return 0;
  else
   if(c=='!')
   {
    do
    {
     c=fgetc(f);
     if(c==EOF) return 0;
    }
    while(c!='\n');
   }
 } while (isspace(c));
 rec[0]=c;
 return fscanf(f,"%128s",rec+1);
}

/***************************/
/* Input a list of strings */
/***************************/
int read_str_list(FILE *f,char ***list,int *size)
{
 int n;
 char word[128];
 char *buf[MAXENTRIES];

 n=0;
 while(fscanf(f,"%128s",word)>0)
  if(strcmp(word,";")==0) break;
  else
   if(word[strlen(word)-1]==';')
   {
    word[strlen(word)-1]='\0';
    buf[n++]=strdup(word);
    break;
   }
   else
    buf[n++]=strdup(word);
   
 *size=n;
 *list=(char **)malloc(sizeof(char *)*n);
 memcpy(*list,buf,sizeof(char *)*n);
 return 0;
}

/************************/
/* Input a list of ints */
/************************/
int read_int_list(FILE *f,int **list,int *size)
{
 int n,c;
 int word;
 int buf[MAXENTRIES];

 n=0;
 while(fscanf(f,"%d",&word)>0)
  buf[n++]=word;
 
 do
 {
  c=fgetc(f);
 } while(isspace(c));

 *size=n;
 *list=(int *)malloc(sizeof(int)*n);
 memcpy(*list,buf,sizeof(int)*n);
 return 0;
}

/****************************/
/* Input a table of doubles */
/****************************/
int read_dbl_table(FILE *f,double **table,int size)
{
 int n,c;

 *table=(double *)malloc(sizeof(double)*size);
 for(n=0;n<size;n++)
  if(fscanf(f,"%lf",(*table)+n)<1) exit(1);
 
 do
 {
  c=fgetc(f);
 } while(isspace(c));

 return 0;
}

/************************************/
/* Input a sparse table of booleans */
/************************************/
int read_bool_table(FILE *f,char ***table,int nrow,int ncol)
{
 int r,c,i;
 char **tbl;

 *table=tbl=(char **)malloc(sizeof(char*)*nrow);
 tbl[0]=(char*)malloc(sizeof(char)*ncol*nrow);
 memset(tbl[0],0,sizeof(char)*ncol*nrow);
 for(r=0;r<nrow;r++)
 {
  if(r>0) tbl[r]=tbl[r-1]+ncol;
  while(fscanf(f,"%d",&i)>0)
   tbl[r][i]=1;

  do
  {
   c=fgetc(f);
  } while(isspace(c));
 }

 return 0;
}

int readdata(const char *filename)
{
 FILE *f;
 char rec[128];

 f=fopen(filename,"r");
 if(f==NULL) return 1;

 while(nextrec(f,rec)>0)
 {
  if(strcmp(rec,"SHARES:")==0 && NSHARES==0)
   read_str_list(f,&SHARES_n,&NSHARES);
  else
  if(strcmp(rec,"REGIONS:")==0 && NREGIONS==0)
   read_str_list(f,&REGIONS_n,&NREGIONS);
  else
  if(strcmp(rec,"TYPES:")==0 && NTYPES==0)
   read_str_list(f,&TYPES_n,&NTYPES);
  else
  if(strcmp(rec,"RISK:")==0 && NRISK==0)
   read_int_list(f,&RISK,&NRISK);
  else
  if(strcmp(rec,"RET:")==0 && NSHARES>0)
   read_dbl_table(f,&RET,NSHARES);
  else
  if(strcmp(rec,"LOC:")==0 && NSHARES>0 && NREGIONS>0)
   read_bool_table(f,&LOC,NREGIONS,NSHARES);
  else
  if(strcmp(rec,"SEC:")==0 && NSHARES>0 && NTYPES>0)
   read_bool_table(f,&SEC,NTYPES,NSHARES);
  else
   break;
 }

 fclose(f);
 return NSHARES<1 || NRISK<1 || NREGIONS<1 || NTYPES<1 ||
        RET==NULL || RISK==NULL || LOC==NULL || SEC==NULL;
}

void testprintout(void)
{
 int i,j;

 printf("Shares(%d):",NSHARES);
 for(i=0;i<NSHARES;i++) printf("%s ",SHARES_n[i]); printf("\n");
 printf("Regions(%d):",NREGIONS);
 for(i=0;i<NREGIONS;i++) printf("%s ",REGIONS_n[i]); printf("\n");
 printf("Types(%d):",NTYPES);
 for(i=0;i<NTYPES;i++) printf("%s ",TYPES_n[i]); printf("\n");
 printf("Risks(%d):",NRISK);
 for(i=0;i<NRISK;i++) printf("%d ",RISK[i]); printf("\n");
 printf("RET:");
 for(i=0;i<NSHARES;i++) printf("%g ",RET[i]); printf("\n");
 printf("LOC:");
 for(i=0;i<NREGIONS;i++)
 {
  for(j=0;j<NSHARES;j++)
   printf(" %d",LOC[i][j]);
  printf("\n");
 }
 printf("SEC:");
 for(i=0;i<NTYPES;i++)
 {
  for(j=0;j<NSHARES;j++)
   printf(" %d",SEC[i][j]);
  printf("\n");
 }
}


foliocb.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file foliocb.c
  ``````````````
  Modeling a MIP problem
  to perform portfolio optimization.

  Same model as in foliomip3.c.
  -- Defining an integer solution callback --

  (c) 2009 Fair Isaac Corporation
      author: S.Heipcke, May 2009, rev. Mar. 2011
********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "xprb.h"
#include "xprs.h"


#define MAXNUM 15                  /* Max. number of different assets */
#define MAXRISK 1.0/3              /* Max. investment into high-risk values */
#define MINREG 0.2                 /* Min. investment per geogr. region */
#define MAXREG 0.5                 /* Max. investment per geogr. region */
#define MAXSEC 0.25                /* Max. investment per ind. sector */
#define MAXVAL 0.2                 /* Max. investment per share */
#define MINVAL 0.1                 /* Min. investment per share */

#define DATAFILE "folio10.cdat"    /* File with problem data */
#define MAXENTRIES 10000


int NSHARES;                       /* Number of shares */
int NRISK;                         /* Number of high-risk shares */
int NREGIONS;                      /* Number of geographical regions */
int NTYPES;                        /* Number of share types */

double *RET;                       /* Estimated return in investment */
int *RISK;                         /* High-risk values among shares */
char **LOC;                        /* Geogr. region of shares */
char **SEC;                        /* Industry sector of shares */

char **SHARES_n;
char **REGIONS_n;
char **TYPES_n;

XPRBvar *frac;                     /* Fraction of capital used per share */
XPRBvar *buy;                      /* 1 if asset is in portfolio, 0 otherwise */

#include "readfoliodata.c_"

void XPRS_CC print_sol(XPRSprob oprob, void *vp);

int main(int argc, char **argv)
{
 int s,r,t;
 XPRBprob prob;
 XPRBctr Risk,Return,Cap,Num;
 XPRBctr *MinReg, *MaxReg, *LimSec, LinkL, LinkU;
 char *MIPSTATUS[] = {"not loaded", "not optimized", "LP optimized",
                      "unfinished (no solution)",
                      "unfinished (solution found)", "infeasible", "optimal",
                      "unbounded"};

 readdata(DATAFILE);               /* Data input from file */

 prob = XPRBnewprob("FolioMIP3");  /* Initialize a new problem in BCL */

/* Create the decision variables (including upper bounds for `frac') */
 frac = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 buy = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 for(s=0;s<NSHARES;s++)
 {
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, MAXVAL);
  buy[s] = XPRBnewvar(prob, XPRB_BV, "buy", 0, 1);
 }

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);          /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, MAXRISK);

/* Limits on geographical distribution */
 MinReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 MaxReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 for(r=0;r<NREGIONS;r++)
 {
  MinReg[r] = XPRBnewctr(prob, "MinReg", XPRB_G);
  MaxReg[r] = XPRBnewctr(prob, "MaxReg", XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(LOC[r][s]>0)
   {
    XPRBaddterm(MinReg[r], frac[s], 1);
    XPRBaddterm(MaxReg[r], frac[s], 1);
   }
  XPRBaddterm(MinReg[r], NULL, MINREG);
  XPRBaddterm(MaxReg[r], NULL, MAXREG);
 }

/* Diversification across industry sectors */
 LimSec = (XPRBctr*)malloc(NTYPES*sizeof(XPRBctr));
 for(t=0;t<NTYPES;t++)
 {
  LimSec[t] = XPRBnewctr(prob, "LimSec", XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(SEC[t][s]>0) XPRBaddterm(LimSec[t], frac[s], 1);
  XPRBaddterm(LimSec[t], NULL, MAXSEC);
 }

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Limit the total number of assets */
 Num = XPRBnewctr(prob, "Num", XPRB_L);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Num, buy[s], 1);
 XPRBaddterm(Num, NULL, MAXNUM);

/* Linking the variables */
 for(s=0;s<NSHARES;s++)
 {
  LinkU = XPRBnewctr(prob, "LinkU", XPRB_L);
  XPRBaddterm(LinkU, frac[s], 1);
  XPRBaddterm(LinkU, buy[s], -MAXVAL);
  LinkL = XPRBnewctr(prob, "LinkL", XPRB_G);
  XPRBaddterm(LinkL, frac[s], 1);
  XPRBaddterm(LinkL, buy[s], -MINVAL);
 }

/* Define an integer solution callback */
 XPRSsetcbintsol(XPRBgetXPRSprob(prob), print_sol, prob);

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBmipoptimize(prob, "");

 printf("Problem status: %s\n", MIPSTATUS[XPRBgetmipstat(prob)]);

 return 0;
}

/**************************Solution printing****************************/

void XPRS_CC print_sol(XPRSprob oprob, void *vp)
{
 int num,s;
 XPRBprob bprob;

 bprob = (XPRBprob)vp;
 XPRBbegincb(bprob, oprob);

 XPRSgetintattrib(oprob, XPRS_MIPSOLS, &num); /* Get number of the solution */

 XPRBsync(bprob, XPRB_XPRS_SOL);              /* Update BCL solution values */
 printf("Solution %d: Total return: %g\n", num, XPRBgetobjval(bprob));
 for(s=0;s<NSHARES;s++)
  if(XPRBgetsol(buy[s])>0.5)
   printf("  %d : %g%% (%g)\n", s, XPRBgetsol(frac[s])*100, XPRBgetsol(buy[s]));

 XPRBendcb(bprob);
}

foliosolpool.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file foliosolpool.c
  ```````````````````
  Modeling a MIP problem
  to perform portfolio optimization.

  Same model as in foliomip3.c.
  -- Using the MIP solution pool --

  (c) 2009 Fair Isaac Corporation
      author: S.Heipcke, June 2009, rev. Mar. 2011
********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "xprb.h"
#include "xprs.h"


#define MAXNUM 7                   /* Max. number of different assets */
#define MAXRISK 1.0/3              /* Max. investment into high-risk values */
#define MINREG 0.2                 /* Min. investment per geogr. region */
#define MAXREG 0.5                 /* Max. investment per geogr. region */
#define MAXSEC 0.25                /* Max. investment per ind. sector */
#define MAXVAL 0.2                 /* Max. investment per share */
#define MINVAL 0.1                 /* Min. investment per share */

#define DATAFILE "folio10.cdat"    /* File with problem data */
#define MAXENTRIES 10000


int NSHARES;                       /* Number of shares */
int NRISK;                         /* Number of high-risk shares */
int NREGIONS;                      /* Number of geographical regions */
int NTYPES;                        /* Number of share types */

double *RET;                       /* Estimated return in investment */
int *RISK;                         /* High-risk values among shares */
char **LOC;                        /* Geogr. region of shares */
char **SEC;                        /* Industry sector of shares */

char **SHARES_n;
char **REGIONS_n;
char **TYPES_n;

XPRBprob prob;
XPRBvar *frac;                     /* Fraction of capital used per share */
XPRBvar *buy;                      /* 1 if asset is in portfolio, 0 otherwise */

#include "readfoliodata.c_"

void print_sol(int num);

int main(int argc, char **argv)
{
 int s,r,t, nSols, nCols, i;
 XPRBctr Risk,Return,Cap,Num;
 XPRBctr *MinReg, *MaxReg, *LimSec, LinkL, LinkU;
 XPRSmipsolpool msp;
 double *xsol;
 int *solIDs;

 readdata(DATAFILE);               /* Data input from file */

 prob = XPRBnewprob("FolioMIP3");  /* Initialize a new problem in BCL */

/* Create the decision variables (including upper bounds for `frac') */
 frac = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 buy = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 for(s=0;s<NSHARES;s++)
 {
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, MAXVAL);
  buy[s] = XPRBnewvar(prob, XPRB_BV, "buy", 0, 1);
 }

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);          /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, MAXRISK);

/* Limits on geographical distribution */
 MinReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 MaxReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 for(r=0;r<NREGIONS;r++)
 {
  MinReg[r] = XPRBnewctr(prob, "MinReg", XPRB_G);
  MaxReg[r] = XPRBnewctr(prob, "MaxReg", XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(LOC[r][s]>0)
   {
    XPRBaddterm(MinReg[r], frac[s], 1);
    XPRBaddterm(MaxReg[r], frac[s], 1);
   }
  XPRBaddterm(MinReg[r], NULL, MINREG);
  XPRBaddterm(MaxReg[r], NULL, MAXREG);
 }

/* Diversification across industry sectors */
 LimSec = (XPRBctr*)malloc(NTYPES*sizeof(XPRBctr));
 for(t=0;t<NTYPES;t++)
 {
  LimSec[t] = XPRBnewctr(prob, "LimSec", XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(SEC[t][s]>0) XPRBaddterm(LimSec[t], frac[s], 1);
  XPRBaddterm(LimSec[t], NULL, MAXSEC);
 }

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Limit the total number of assets */
 Num = XPRBnewctr(prob, "Num", XPRB_L);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Num, buy[s], 1);
 XPRBaddterm(Num, NULL, MAXNUM);

/* Linking the variables */
 for(s=0;s<NSHARES;s++)
 {
  LinkU = XPRBnewctr(prob, "LinkU", XPRB_L);
  XPRBaddterm(LinkU, frac[s], 1);
  XPRBaddterm(LinkU, buy[s], -MAXVAL);
  LinkL = XPRBnewctr(prob, "LinkL", XPRB_G);
  XPRBaddterm(LinkL, frac[s], 1);
  XPRBaddterm(LinkL, buy[s], -MINVAL);
 }


/* Create a MIP solution pool and attach it to the problem
   (so it collects the solutions) */
 XPRS_msp_create(&msp);
 XPRS_msp_probattach(msp, XPRBgetXPRSprob(prob));

/* Avoid storing of duplicate solutions (3: compare discrete variables only) */
 XPRS_msp_setintcontrol(msp, XPRS_MSP_DUPLICATESOLUTIONSPOLICY, 3);

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBmipoptimize(prob, "");

/* Setup some resources to iterate through the solutions stored
   in the MIP solution pool */
 XPRSgetintattrib(XPRBgetXPRSprob(prob), XPRS_ORIGINALCOLS, &nCols);
 XPRS_msp_getintattrib(msp, XPRS_MSP_SOLUTIONS, &nSols);
 xsol = (double *) malloc(nCols * sizeof(double));
 solIDs = (int *) malloc(nSols * sizeof(int));

                                         /* Get the solution IDs */
 XPRS_msp_getsollist(msp, XPRBgetXPRSprob(prob), XPRS_MSP_SOLPRB_OBJ, 1, 1,
		     nSols, solIDs, &nSols, NULL);

/* Display all solutions from the pool */
 for(i=0; i<nSols; i++)
 {                                       /* Get the solution */
  XPRS_msp_getsol(msp, solIDs[i], NULL, xsol, 0, nCols - 1, NULL);
  XPRBloadmipsol(prob, xsol, nCols, 0);  /* Load the solution into BCL */
  print_sol(i+1);                        /* Display the solution */
 }

 free(xsol);
 XPRS_msp_destroy(msp);

 return 0;
}


/* Solution printing */
void print_sol(int num)
{
 int s;

 printf("Solution %d: Total return: %g\n", num, XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  if(XPRBgetsol(buy[s])>0.5)
   printf("  %s : %g%% (%g)\n", SHARES_n[s], XPRBgetsol(frac[s])*100,
          XPRBgetsol(buy[s]));
}

folioenumsol.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file folioenumsol.c
  ```````````````````
  Modeling a MIP problem
  to perform portfolio optimization.

  Same model as in foliomip3.c.
  -- Using the solution enumerator --

  (c) 2009 Fair Isaac Corporation
      author: S.Heipcke, May 2009, rev. Jul. 2014
********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "xprb.h"
#include "xprs.h"
#include "xprs_mse_defaulthandler.h"


#define MAXNUM 7                   /* Max. number of different assets */
#define MAXRISK 1.0/3              /* Max. investment into high-risk values */
#define MINREG 0.2                 /* Min. investment per geogr. region */
#define MAXREG 0.5                 /* Max. investment per geogr. region */
#define MAXSEC 0.25                /* Max. investment per ind. sector */
#define MAXVAL 0.2                 /* Max. investment per share */
#define MINVAL 0.1                 /* Min. investment per share */

#define DATAFILE "folio10.cdat"    /* File with problem data */
#define MAXENTRIES 10000


int NSHARES;                       /* Number of shares */
int NRISK;                         /* Number of high-risk shares */
int NREGIONS;                      /* Number of geographical regions */
int NTYPES;                        /* Number of share types */

double *RET;                       /* Estimated return in investment */
int *RISK;                         /* High-risk values among shares */
char **LOC;                        /* Geogr. region of shares */
char **SEC;                        /* Industry sector of shares */

char **SHARES_n;
char **REGIONS_n;
char **TYPES_n;

XPRBprob prob;
XPRBvar *frac;                     /* Fraction of capital used per share */
XPRBvar *buy;                      /* 1 if asset is in portfolio, 0 otherwise */

#include "readfoliodata.c_"

void print_sol(int num);

int main(int argc, char **argv)
{
 int s,r,t, nMaxSols, nSols, nCols, i;
 XPRBctr Risk,Return,Cap,Num;
 XPRBctr *MinReg, *MaxReg, *LimSec, LinkL, LinkU;
 XPRSmipsolpool msp;
 XPRSmipsolenum mse;
 double *xsol;
 int *solIDs;

 readdata(DATAFILE);               /* Data input from file */

 prob = XPRBnewprob("FolioMIP3");  /* Initialize a new problem in BCL */

/* Create the decision variables (including upper bounds for `frac') */
 frac = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 buy = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 for(s=0;s<NSHARES;s++)
 {
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, MAXVAL);
  buy[s] = XPRBnewvar(prob, XPRB_BV, "buy", 0, 1);
 }

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);          /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, MAXRISK);

/* Limits on geographical distribution */
 MinReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 MaxReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 for(r=0;r<NREGIONS;r++)
 {
  MinReg[r] = XPRBnewctr(prob, "MinReg", XPRB_G);
  MaxReg[r] = XPRBnewctr(prob, "MaxReg", XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(LOC[r][s]>0)
   {
    XPRBaddterm(MinReg[r], frac[s], 1);
    XPRBaddterm(MaxReg[r], frac[s], 1);
   }
  XPRBaddterm(MinReg[r], NULL, MINREG);
  XPRBaddterm(MaxReg[r], NULL, MAXREG);
 }

/* Diversification across industry sectors */
 LimSec = (XPRBctr*)malloc(NTYPES*sizeof(XPRBctr));
 for(t=0;t<NTYPES;t++)
 {
  LimSec[t] = XPRBnewctr(prob, "LimSec", XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(SEC[t][s]>0) XPRBaddterm(LimSec[t], frac[s], 1);
  XPRBaddterm(LimSec[t], NULL, MAXSEC);
 }

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Limit the total number of assets */
 Num = XPRBnewctr(prob, "Num", XPRB_L);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Num, buy[s], 1);
 XPRBaddterm(Num, NULL, MAXNUM);

/* Linking the variables */
 for(s=0;s<NSHARES;s++)
 {
  LinkU = XPRBnewctr(prob, "LinkU", XPRB_L);
  XPRBaddterm(LinkU, frac[s], 1);
  XPRBaddterm(LinkU, buy[s], -MAXVAL);
  LinkL = XPRBnewctr(prob, "LinkL", XPRB_G);
  XPRBaddterm(LinkL, frac[s], 1);
  XPRBaddterm(LinkL, buy[s], -MINVAL);
 }


/* Create a MIP solution pool & enumerator */
 XPRS_mse_create(&mse);
 XPRS_msp_create(&msp);

/* Load matrix into the Optimizer, then hand over to solution enumerator */
 XPRBloadmat(prob);

/* Disable heuristics to avoid duplicate solutions being stored */
 XPRSsetintcontrol(XPRBgetXPRSprob(prob), XPRS_HEURSTRATEGY, 0);

 nMaxSols = 15;                    /* Max. number of solutions to return */

/* Solve the problem */
 XPRS_mse_maxim(mse, XPRBgetXPRSprob(prob), msp, XPRS_mse_defaulthandler,
                NULL, &nMaxSols);

/* Setup some resources to iterate through the solutions stored
   in the MIP solution pool */
 XPRSgetintattrib(XPRBgetXPRSprob(prob), XPRS_ORIGINALCOLS, &nCols);
 XPRS_mse_getintattrib(mse, XPRS_MSE_SOLUTIONS, &nSols);

 xsol = (double *) malloc(nCols * sizeof(double));
 solIDs = (int *) malloc(nSols * sizeof(int));

/* Get the solution IDs */
 XPRS_mse_getsollist(mse, XPRS_MSE_METRIC_MIPOBJECT, 1, nSols,
                     solIDs, &nSols, NULL);

/* Display all solutions from the pool */
 for(i=0; i<nSols; i++)
 {                                       /* Get the solution */
  XPRS_msp_getsol(msp, solIDs[i], NULL, xsol, 0, nCols - 1, NULL);
  XPRBloadmipsol(prob, xsol, nCols, 0);  /* Load the solution into BCL */
  print_sol(i+1);                        /* Display the solution */
 }

 free(xsol);
 XPRS_mse_destroy(mse);
 XPRS_msp_destroy(msp);

 return 0;
}


/* Solution printing */
void print_sol(int num)
{
 int s;

 printf("Solution %d: Total return: %g\n", num, XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  if(XPRBgetsol(buy[s])>0.5)
   printf("  %s : %g%% (%g)\n", SHARES_n[s], XPRBgetsol(frac[s])*100,
          XPRBgetsol(buy[s]));
}

folioinfeas.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file folioinfeas.c
  ``````````````````
  Modeling a MIP problem
  to perform portfolio optimization.

  Same model as in foliomip3.c.
  -- Infeasible model parameter values --
  -- Handling infeasibility through auxiliary variables --

  (c) 2009 Fair Isaac Corporation
      author: S.Heipcke, June 2009, rev. Mar. 2011
********************************************************/

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


#define MAXNUM 4                   /* Max. number of different assets */
#define MAXRISK 1.0/3              /* Max. investment into high-risk values */
#define MINREG 0.3                 /* Min. investment per geogr. region */
#define MAXREG 0.5                 /* Max. investment per geogr. region */
#define MAXSEC 0.15                /* Max. investment per ind. sector */
#define MAXVAL 0.2                 /* Max. investment per share */
#define MINVAL 0.1                 /* Min. investment per share */

#define DATAFILE "folio10.cdat"    /* File with problem data */
#define MAXENTRIES 10000


int NSHARES;                       /* Number of shares */
int NRISK;                         /* Number of high-risk shares */
int NREGIONS;                      /* Number of geographical regions */
int NTYPES;                        /* Number of share types */

double *RET;                       /* Estimated return in investment */
int *RISK;                         /* High-risk values among shares */
char **LOC;                        /* Geogr. region of shares */
char **SEC;                        /* Industry sector of shares */

char **SHARES_n;
char **REGIONS_n;
char **TYPES_n;

#include "readfoliodata.c_"

int main(int argc, char **argv)
{
 int s,r,t;
 double sumf, penalty;
 XPRBprob prob;
 XPRBctr Risk,Return,Cap,Num;
 XPRBctr *MinReg, *MaxReg, *LimSec, LinkL, LinkU;
 XPRBvar *frac;                   /* Fraction of capital used per share */
 XPRBvar *buy;                    /* 1 if asset is in portfolio, 0 otherwise */
 XPRBvar devRisk, devNum, *devMinReg, *devMaxReg, *devSec;
 char *MIPSTATUS[] = {"not loaded", "not optimized", "LP optimized",
                      "unfinished (no solution)",
                      "unfinished (solution found)", "infeasible", "optimal",
                      "unbounded"};

 readdata(DATAFILE);               /* Data input from file */

 prob = XPRBnewprob("FolioMIP3inf");  /* Initialize a new problem in BCL */

/* Create the decision variables (including upper bounds for `frac') */
 frac = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 buy = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 for(s=0;s<NSHARES;s++)
 {
  frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, MAXVAL);
  buy[s] = XPRBnewvar(prob, XPRB_BV, "buy", 0, 1);
 }

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);          /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, MAXRISK);

/* Limits on geographical distribution */
 MinReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 MaxReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 for(r=0;r<NREGIONS;r++)
 {
  MinReg[r] = XPRBnewctr(prob, "MinReg", XPRB_G);
  MaxReg[r] = XPRBnewctr(prob, "MaxReg", XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(LOC[r][s]>0)
   {
    XPRBaddterm(MinReg[r], frac[s], 1);
    XPRBaddterm(MaxReg[r], frac[s], 1);
   }
  XPRBaddterm(MinReg[r], NULL, MINREG);
  XPRBaddterm(MaxReg[r], NULL, MAXREG);
 }

/* Diversification across industry sectors */
 LimSec = (XPRBctr*)malloc(NTYPES*sizeof(XPRBctr));
 for(t=0;t<NTYPES;t++)
 {
  LimSec[t] = XPRBnewctr(prob, "LimSec", XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(SEC[t][s]>0) XPRBaddterm(LimSec[t], frac[s], 1);
  XPRBaddterm(LimSec[t], NULL, MAXSEC);
 }

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Limit the total number of assets */
 Num = XPRBnewctr(prob, "Num", XPRB_L);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Num, buy[s], 1);
 XPRBaddterm(Num, NULL, MAXNUM);

/* Linking the variables */
 for(s=0;s<NSHARES;s++)
 {
  LinkU = XPRBnewctr(prob, "LinkU", XPRB_L);
  XPRBaddterm(LinkU, frac[s], 1);
  XPRBaddterm(LinkU, buy[s], -MAXVAL);
  LinkL = XPRBnewctr(prob, "LinkL", XPRB_G);
  XPRBaddterm(LinkL, frac[s], 1);
  XPRBaddterm(LinkL, buy[s], -MINVAL);
 }

/* Solve the problem */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBmipoptimize(prob, "");

 printf("Problem status: %s\n", MIPSTATUS[XPRBgetmipstat(prob)]);

 if (XPRBgetmipstat(prob)==XPRB_MIP_INFEAS)
 {
  printf("Original problem infeasible. Adding deviation variables\n");

  /* Define deviation variables and add them to the constraints
     to make problem solvable */
  devRisk = XPRBnewvar(prob, XPRB_PL, "devRisk", 0, XPRB_INFINITY);
  XPRBaddterm(Risk, devRisk, -1);

  devMinReg = (XPRBvar*)malloc(NREGIONS*sizeof(XPRBvar));
  devMaxReg = (XPRBvar*)malloc(NREGIONS*sizeof(XPRBvar));
  for(r=0;r<NREGIONS;r++)
  {                                  /* Only allow small deviations */
   devMinReg[r] = XPRBnewvar(prob, XPRB_PL, "devMinReg", 0, MAXREG/2);
   XPRBaddterm(MinReg[r], devMinReg[r], 1);
   devMaxReg[r] = XPRBnewvar(prob, XPRB_PL, "devMaxReg", 0, MAXREG/2);
   XPRBaddterm(MaxReg[r], devMaxReg[r], -1);
  }

  devSec = (XPRBvar*)malloc(NTYPES*sizeof(XPRBvar));
  for(t=0;t<NTYPES;t++)
  {
   devSec[t] = XPRBnewvar(prob, XPRB_PL, "devSec", 0, MAXSEC/2);
   XPRBaddterm(LimSec[t], devSec[t], -1);
  }

  devNum = XPRBnewvar(prob, XPRB_PL, "devNum", 0, XPRB_INFINITY);
  XPRBaddterm(Num, devNum, -1);


 /* Resolve the problem with penalty terms added to the objective */
  penalty = -10;
  XPRBaddterm(Return, devRisk, penalty);
  for(r=0;r<NREGIONS;r++)  XPRBaddterm(Return, devMinReg[r], penalty);
  for(r=0;r<NREGIONS;r++)  XPRBaddterm(Return, devMaxReg[r], penalty);
  for(t=0;t<NTYPES;t++)  XPRBaddterm(Return, devSec[t], penalty);
  XPRBaddterm(Return, devNum, penalty);
  XPRBsetobj(prob,Return);          /* Set the new objective function */

  XPRBmipoptimize(prob, "");

  if (XPRBgetmipstat(prob)==XPRB_MIP_INFEAS)
  {
   printf("No solution after relaxation\n");
   return 0;
  }
  else
  {
   printf("Constraint violations:\n");
   printf("  Constraint            Activity  Deviation  Bound(s)\n");
   printf("  Risk                    %1.2f\t  %1.2f\t  (%1.2f)\n",
          XPRBgetact(Risk)+XPRBgetsol(devRisk),
          XPRBgetsol(devRisk), MAXRISK);
   for(r=0;r<NREGIONS;r++)
   {
    sumf=0;
    for(s=0;s<NSHARES;s++) if(LOC[r][s]>0) sumf+=XPRBgetsol(frac[s]);
    printf("  Region %-11s      %1.2f\t  %1.2f\t  (%g-%g)\n", REGIONS_n[r], sumf,
           XPRBgetsol(devMaxReg[r])-XPRBgetsol(devMinReg[r]),
           MINREG, MAXREG);
   }
   for(t=0;t<NTYPES;t++)
   {
    printf("  Sector %-14s   %1.2f\t  %1.2f\t  (%g)\n", TYPES_n[t],
           XPRBgetact(LimSec[t])+XPRBgetsol(devSec[t]), XPRBgetsol(devSec[t]),
           MAXSEC);
   }
   printf("  Number of assets        %1.2f\t  %1.2f\t  (%d)\n",
          XPRBgetact(Num)+XPRBgetsol(devNum), XPRBgetsol(devNum), MAXNUM);
  }
 }

/* Solution printing */
 printf("Total return: %g\n", XPRBgetobjval(prob));
 for(s=0;s<NSHARES;s++)
  if(XPRBgetsol(buy[s])>0.5)
   printf("  %d : %g%% (%g)\n", s, XPRBgetsol(frac[s])*100, XPRBgetsol(buy[s]));

 return 0;
}

folioiis.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file folioiis.c
  ```````````````
  Modeling a MIP problem
  to perform portfolio optimization.

  Same model as in foliomip3.c.
  -- Infeasible model parameter values --
  -- Retrieving IIS --

  (c) 2009 Fair Isaac Corporation
      author: S.Heipcke, June 2009, rev. Mar. 2011
********************************************************/

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


#define MAXNUM 5                   /* Max. number of different assets */
#define MAXRISK 1.0/3              /* Max. investment into high-risk values */
#define MINREG 0.1                 /* Min. investment per geogr. region */
#define MAXREG 0.2                 /* Max. investment per geogr. region */
#define MAXSEC 0.1                 /* Max. investment per ind. sector */
#define MAXVAL 0.2                 /* Max. investment per share */
#define MINVAL 0.1                 /* Min. investment per share */

#define DATAFILE "folio10.cdat"    /* File with problem data */
#define MAXENTRIES 10000


int NSHARES;                       /* Number of shares */
int NRISK;                         /* Number of high-risk shares */
int NREGIONS;                      /* Number of geographical regions */
int NTYPES;                        /* Number of share types */

double *RET;                       /* Estimated return in investment */
int *RISK;                         /* High-risk values among shares */
char **LOC;                        /* Geogr. region of shares */
char **SEC;                        /* Industry sector of shares */

char **SHARES_n;
char **REGIONS_n;
char **TYPES_n;

#include "readfoliodata.c_"

int main(int argc, char **argv)
{
 int s,r,t,i;
 XPRBprob prob;
 XPRBctr Risk,Return,Cap,Num;
 XPRBctr *MinReg, *MaxReg, *LimSec, LinkL, LinkU;
 XPRBvar *frac;                   /* Fraction of capital used per share */
 XPRBvar *buy;                    /* 1 if asset is in portfolio, 0 otherwise */
 XPRBctr *iisctr;
 XPRBvar *iisvar;
 int numv, numc, numiis;

 readdata(DATAFILE);               /* Data input from file */

 prob = XPRBnewprob("FolioMIP3inf");  /* Initialize a new problem in BCL */

/* Create the decision variables (including upper bounds for `frac') */
 frac = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 buy = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 for(s=0;s<NSHARES;s++)
 {
  frac[s] = XPRBnewvar(prob, XPRB_PL, XPRBnewname("frac(%s)",SHARES_n[s]), 0, MAXVAL);
  buy[s] = XPRBnewvar(prob, XPRB_BV, XPRBnewname("buy(%s)",SHARES_n[s]), 0, 1);
 }

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);          /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, MAXRISK);

/* Limits on geographical distribution */
 MinReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 MaxReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 for(r=0;r<NREGIONS;r++)
 {
  MinReg[r] = XPRBnewctr(prob, XPRBnewname("MinReg(%s)",REGIONS_n[r]), XPRB_G);
  MaxReg[r] = XPRBnewctr(prob, XPRBnewname("MaxReg(%s)",REGIONS_n[r]), XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(LOC[r][s]>0)
   {
    XPRBaddterm(MinReg[r], frac[s], 1);
    XPRBaddterm(MaxReg[r], frac[s], 1);
   }
  XPRBaddterm(MinReg[r], NULL, MINREG);
  XPRBaddterm(MaxReg[r], NULL, MAXREG);
 }

/* Diversification across industry sectors */
 LimSec = (XPRBctr*)malloc(NTYPES*sizeof(XPRBctr));
 for(t=0;t<NTYPES;t++)
 {
  LimSec[t] = XPRBnewctr(prob, XPRBnewname("LimSec(%s)",TYPES_n[t]), XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(SEC[t][s]>0) XPRBaddterm(LimSec[t], frac[s], 1);
  XPRBaddterm(LimSec[t], NULL, MAXSEC);
 }

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Limit the total number of assets */
 Num = XPRBnewctr(prob, "Num", XPRB_L);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Num, buy[s], 1);
 XPRBaddterm(Num, NULL, MAXNUM);

/* Linking the variables */
 for(s=0;s<NSHARES;s++)
 {
  LinkU = XPRBnewctr(prob, "LinkU", XPRB_L);
  XPRBaddterm(LinkU, frac[s], 1);
  XPRBaddterm(LinkU, buy[s], -MAXVAL);
  LinkL = XPRBnewctr(prob, "LinkL", XPRB_G);
  XPRBaddterm(LinkL, frac[s], 1);
  XPRBaddterm(LinkL, buy[s], -MINVAL);
 }

/* Solve the problem (LP) */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBlpoptimize(prob, "");

 if (XPRBgetlpstat(prob)==XPRB_LP_INFEAS)
 {
  printf("LP infeasible. Retrieving IIS.\n");

  numiis=XPRBgetnumiis(prob);     /* Get the number of independent IIS */
  printf("Number of IIS: %d\n", numiis);
  for(s=1;s<=numiis;s++)
  {
   XPRBgetiis(prob, &iisvar, &numv, &iisctr, &numc, s);
   printf("IIS %d:  %d variables, %d constraints\n", s, numv, numc);
   if (numv>0)
   {                              /* Print all variables in the IIS */
    printf("        Variables: ");
    for(i=0;i<numv;i++) printf("%s ", XPRBgetvarname(iisvar[i]));
    printf("\n");
    XPRBfreemem(iisvar);          /* Free the array of variables */
   }
   if (numc>0)
   {                              /* Print all constraints in the IIS */
    printf("        Constraints: ");
    for(i=0;i<numc;i++) printf("%s ", XPRBgetctrname(iisctr[i]));
    printf("\n");
    XPRBfreemem(iisctr);          /* Free the array of constraints */
   }
  }
 }
 else
  printf("Solution status: %d\n", XPRBgetlpstat(prob));

 return 0;
}

foliomiis.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file foliomiis.c
  ````````````````
  Modeling a MIP problem
  to perform portfolio optimization.

  Same model as in foliomip3.c.
  -- Infeasible model parameter values --
  -- Retrieving MIIS --

  (c) 2011 Fair Isaac Corporation
      author: S.Heipcke, Mar. 2011
********************************************************/

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


#define MAXNUM 5                   /* Max. number of different assets */
#define MAXRISK 1.0/4              /* Max. investment into high-risk values */
#define MINREG 0.1                 /* Min. investment per geogr. region */
#define MAXREG 0.25                /* Max. investment per geogr. region */
#define MAXSEC 0.15                /* Max. investment per ind. sector */
#define MAXVAL 0.225               /* Max. investment per share */
#define MINVAL 0.1                 /* Min. investment per share */

#define DATAFILE "folio5.cdat"     /* File with problem data */
#define MAXENTRIES 10000


int NSHARES;                       /* Number of shares */
int NRISK;                         /* Number of high-risk shares */
int NREGIONS;                      /* Number of geographical regions */
int NTYPES;                        /* Number of share types */

double *RET;                       /* Estimated return in investment */
int *RISK;                         /* High-risk values among shares */
char **LOC;                        /* Geogr. region of shares */
char **SEC;                        /* Industry sector of shares */

char **SHARES_n;
char **REGIONS_n;
char **TYPES_n;

#include "readfoliodata.c_"

int main(int argc, char **argv)
{
 int s,r,t,i;
 XPRBprob prob;
 XPRBctr Risk,Return,Cap,Num;
 XPRBctr *MinReg, *MaxReg, *LimSec, LinkL, LinkU;
 XPRBvar *frac;                   /* Fraction of capital used per share */
 XPRBvar *buy;                    /* 1 if asset is in portfolio, 0 otherwise */
 XPRBctr *iisctr;
 XPRBvar *iisvar;
 int numv, numc, numiis;

 readdata(DATAFILE);               /* Data input from file */

 prob = XPRBnewprob("FolioMIP3inf");  /* Initialize a new problem in BCL */

/* Create the decision variables (including upper bounds for `frac') */
 frac = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 buy = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
 for(s=0;s<NSHARES;s++)
 {
  frac[s] = XPRBnewvar(prob, XPRB_PL, XPRBnewname("frac(%s)",SHARES_n[s]), 0, MAXVAL);
  buy[s] = XPRBnewvar(prob, XPRB_BV, XPRBnewname("buy(%s)",SHARES_n[s]), 0, 1);
 }

/* Objective: total return */
 Return = XPRBnewctr(prob, "Return", XPRB_N);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Return, frac[s], RET[s]);
 XPRBsetobj(prob,Return);          /* Set the objective function */

/* Limit the percentage of high-risk values */
 Risk = XPRBnewctr(prob, "Risk", XPRB_L);
 for(s=0;s<NRISK;s++) XPRBaddterm(Risk, frac[RISK[s]], 1);
 XPRBaddterm(Risk, NULL, MAXRISK);

/* Limits on geographical distribution */
 MinReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 MaxReg = (XPRBctr*)malloc(NREGIONS*sizeof(XPRBctr));
 for(r=0;r<NREGIONS;r++)
 {
  MinReg[r] = XPRBnewctr(prob, XPRBnewname("MinReg(%s)",REGIONS_n[r]), XPRB_G);
  MaxReg[r] = XPRBnewctr(prob, XPRBnewname("MaxReg(%s)",REGIONS_n[r]), XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(LOC[r][s]>0)
   {
    XPRBaddterm(MinReg[r], frac[s], 1);
    XPRBaddterm(MaxReg[r], frac[s], 1);
   }
  XPRBaddterm(MinReg[r], NULL, MINREG);
  XPRBaddterm(MaxReg[r], NULL, MAXREG);
 }

/* Diversification across industry sectors */
 LimSec = (XPRBctr*)malloc(NTYPES*sizeof(XPRBctr));
 for(t=0;t<NTYPES;t++)
 {
  LimSec[t] = XPRBnewctr(prob, XPRBnewname("LimSec(%s)",TYPES_n[t]), XPRB_L);
  for(s=0;s<NSHARES;s++)
   if(SEC[t][s]>0) XPRBaddterm(LimSec[t], frac[s], 1);
  XPRBaddterm(LimSec[t], NULL, MAXSEC);
 }

/* Spend all the capital */
 Cap = XPRBnewctr(prob, "Cap", XPRB_E);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Cap, frac[s], 1);
 XPRBaddterm(Cap, NULL, 1);

/* Limit the total number of assets */
 Num = XPRBnewctr(prob, "Num", XPRB_L);
 for(s=0;s<NSHARES;s++) XPRBaddterm(Num, buy[s], 1);
 XPRBaddterm(Num, NULL, MAXNUM);

/* Linking the variables */
 for(s=0;s<NSHARES;s++)
 {
  LinkU = XPRBnewctr(prob, XPRBnewname("LinkU(%s)",SHARES_n[s]), XPRB_L);
  XPRBaddterm(LinkU, frac[s], 1);
  XPRBaddterm(LinkU, buy[s], -MAXVAL);
  LinkL = XPRBnewctr(prob, XPRBnewname("LinkL(%s)",SHARES_n[s]), XPRB_G);
  XPRBaddterm(LinkL, frac[s], 1);
  XPRBaddterm(LinkL, buy[s], -MINVAL);
 }

/* Solve the problem (MIP) */
 XPRBsetsense(prob, XPRB_MAXIM);
 XPRBmipoptimize(prob, "");

 if (XPRBgetmipstat(prob)==XPRB_MIP_INFEAS)
 {
  printf("MIP infeasible. Retrieving IIS.\n");

  numiis=XPRBgetnumiis(prob);     /* Get the number of independent IIS */
  printf("Number of IIS: %d\n", numiis);
  for(s=1;s<=numiis;s++)
  {
   XPRBgetmiis(prob, &iisvar, &numv, &iisctr, &numc, NULL, NULL, s);
   printf("IIS %d:  %d variables, %d constraints\n", s, numv, numc);
   if (numv>0)
   {                              /* Print all variables in the IIS */
    printf("        Variables: ");
    for(i=0;i<numv;i++) printf("%s ", XPRBgetvarname(iisvar[i]));
    printf("\n");
    XPRBfreemem(iisvar);          /* Free the array of variables */
   }
   if (numc>0)
   {                              /* Print all constraints in the IIS */
    printf("        Constraints: ");
    for(i=0;i<numc;i++) printf("%s ", XPRBgetctrname(iisctr[i]));
    printf("\n");
    XPRBfreemem(iisctr);          /* Free the array of constraints */
   }
  }
 }
 else
  printf("Feasible or search unfinished!\n");

 return 0;
}

foliorep.c
/********************************************************
  Xpress-BCL C Example Problems
  =============================

  file foliorep.c
  ```````````````
  Modeling a MIP problem
  to perform portfolio optimization.

  Same model as in foliomip3.c.
  -- Infeasible model parameter values --
  -- Repairing infeasibilities --

  (c) 2009 Fair Isaac Corporation
      author: S.Heipcke, June 2009, rev. Oct. 2014
********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "xprb.h"
#include "xprs.h"


#define MAXNUM 4                   /* Max. number of different assets */
#define MAXRISK 1.0/3              /* Max. investment into high-risk values */
#define MINREG 0.3                 /* Min. investment per geogr. region */
#define MAXREG 0.5                 /* Max. investment per geogr. region */
#define MAXSEC 0.15                /* Max. investment per ind. sector */
#define MAXVAL 0.2                 /* Max. investment per share */
#define MINVAL 0.1                 /* Min. investment per share */

#define DATAFILE "folio10.cdat"    /* File with problem data */
#define MAXENTRIES 10000


int NSHARES;                       /* Number of shares */
int NRISK;                         /* Number of high-risk shares */
int NREGIONS;                      /* Number of geographical regions */
int NTYPES;                        /* Number of share types */

double *RET;                       /* Estimated return in investment */
int *RISK;                         /* High-risk values among shares */
char **LOC;                        /* Geogr. region of shares */
char **SEC;                        /* Industry sector of shares */

char **SHARES_n;
char **REGIONS_n;
char **TYPES_n;

XPRBprob prob;
XPRBvar *frac;                     /* Fraction of capital used per share */
XPRBvar *buy;                      /* 1 if asset is in portfolio, 0 otherwise */
XPRBctr *allCtr;                   /* array containing all defined contraints */
int allCtrCount = 0;               /* number of constraints in allCtr array */

#include "readfoliodata.c_"

void print_sol_opt(void);
void print_violated(void);

int main(int argc, char **argv)
{
  int s, r, t;
  XPRBctr Return, *Risk, *Cap, *Num;
  XPRBctr *MinReg, *MaxReg, *LimSec, *LinkL, *LinkU;

  readdata(DATAFILE);               /* Data input from file */

  prob = XPRBnewprob("FolioMIP3inf");  /* Initialize a new problem in BCL */

  /* Create the decision variables (including upper bounds for `frac') */
  frac = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
  buy = (XPRBvar*)malloc(NSHARES*sizeof(XPRBvar));
  for (s = 0; s<NSHARES; s++) {
    frac[s] = XPRBnewvar(prob, XPRB_PL, "frac", 0, MAXVAL);
    buy[s] = XPRBnewvar(prob, XPRB_BV, "buy", 0, 1);
  }

  /* Objective: total return */
  Return = XPRBnewctr(prob, "Return", XPRB_N);
  for (s = 0; s<NSHARES; s++) XPRBaddterm(Return, frac[s], RET[s]);
  XPRBsetobj(prob, Return);          /* Set the objective function */

  /* allocate memory for all constraints: Risk(1), Cap(1), Num(1), MinReg(NREGIONS), MaxReg(NREGIONS), LimSec(NTYPES), LinkU(NSHARES), LinkL(NSHARES) */
  allCtr = (XPRBctr*)malloc(sizeof(XPRBctr)* (3 + 2 * NREGIONS + NTYPES + 2 * NSHARES));
  /* init constraint pointers */
  Risk   = &allCtr[allCtrCount++];
  Cap    = &allCtr[allCtrCount++];
  Num    = &allCtr[allCtrCount++];
  MinReg = &allCtr[allCtrCount]; allCtrCount += NREGIONS;
  MaxReg = &allCtr[allCtrCount]; allCtrCount += NREGIONS;
  LimSec = &allCtr[allCtrCount]; allCtrCount += NTYPES;
  LinkU  = &allCtr[allCtrCount]; allCtrCount += NSHARES;
  LinkL  = &allCtr[allCtrCount]; allCtrCount += NSHARES;

  /* Limit the percentage of high-risk values */
  *Risk = XPRBnewctr(prob, "Risk", XPRB_L);
  for (s = 0; s<NRISK; s++) XPRBaddterm(*Risk, frac[RISK[s]], 1);
  XPRBaddterm(*Risk, NULL, MAXRISK);

  /* Limits on geographical distribution */
  for (r = 0; r<NREGIONS; r++) {
    MinReg[r] = XPRBnewctr(prob, XPRBnewname("MinReg(%s)", REGIONS_n[r]), XPRB_G);
    MaxReg[r] = XPRBnewctr(prob, XPRBnewname("MaxReg(%s)", REGIONS_n[r]), XPRB_L);
    for (s = 0; s<NSHARES; s++)
      if (LOC[r][s]>0) {
        XPRBaddterm(MinReg[r], frac[s], 1);
        XPRBaddterm(MaxReg[r], frac[s], 1);
      }
    XPRBaddterm(MinReg[r], NULL, MINREG);
    XPRBaddterm(MaxReg[r], NULL, MAXREG);
  }

  /* Diversification across industry sectors */
  for (t = 0; t<NTYPES; t++) {
    LimSec[t] = XPRBnewctr(prob, XPRBnewname("LimSec(%s)", TYPES_n[t]), XPRB_L);
    for (s = 0; s<NSHARES; s++) if (SEC[t][s]>0) XPRBaddterm(LimSec[t], frac[s], 1);
    XPRBaddterm(LimSec[t], NULL, MAXSEC);
  }

  /* Spend all the capital */
  *Cap = XPRBnewctr(prob, "Cap", XPRB_E);
  for (s = 0; s<NSHARES; s++) XPRBaddterm(*Cap, frac[s], 1);
  XPRBaddterm(*Cap, NULL, 1);

  /* Limit the total number of assets */
  *Num = XPRBnewctr(prob, "Num", XPRB_L);
  for (s = 0; s<NSHARES; s++) XPRBaddterm(*Num, buy[s], 1);
  XPRBaddterm(*Num, NULL, MAXNUM);

  /* Linking the variables */
  for (s = 0; s<NSHARES; s++) {
    LinkU[s] = XPRBnewctr(prob, XPRBnewname("LinkU(%s)", SHARES_n[s]), XPRB_L);
    XPRBaddterm(LinkU[s], frac[s], 1);
    XPRBaddterm(LinkU[s], buy[s], -MAXVAL);
    LinkL[s] = XPRBnewctr(prob, XPRBnewname("LinkL(%s)", SHARES_n[s]), XPRB_G);
    XPRBaddterm(LinkL[s], frac[s], 1);
    XPRBaddterm(LinkL[s], buy[s], -MINVAL);
  }

  /* Solve the problem (LP) */
  XPRBsetmsglevel(prob, 1);
  XPRBsetsense(prob, XPRB_MAXIM);
  XPRBlpoptimize(prob, "");

  if (XPRBgetlpstat(prob) == XPRB_LP_INFEAS) {
    char *rstat[] = { "relaxed optimum found", "relaxed problem infeasible",
      "relaxed problem unbounded", "solution nonoptimal for original objective",
      "error", "numerical instability" };
    double *lrp, *grp; /* Selectors for LEG / GEQ constraints */
    double *lbp, *ubp; /* Selector for lower / upper bounds on vars */
    double delta;
    int ncol, nrow, repstatus;
    XPRSprob op;

    printf("LP infeasible. Start infeasibility repair.\n");

    op = XPRBgetXPRSprob(prob);     /* Retrieve the Optimizer problem */

    /* Must use the weighted infeasibility repair method since
    only some constraints of each type may be relaxed */

    /*
    lrp: (affects = and <= rows)
    ax - aux_var  = b
    ax - aux_var <= b
    grp: (affects = and >= rows)
    ax + aux_var  = b
    ax + aux_var >= b
    lbp:
    x_i + aux_var >= l
    ubp:
    x_i - aux_var <= u
    */

    XPRSgetintattrib(op, XPRS_ORIGINALCOLS, &ncol);
    XPRSgetintattrib(op, XPRS_ORIGINALROWS, &nrow);
    lrp = (double *)calloc(nrow, sizeof(double));
    grp = (double *)calloc(nrow, sizeof(double));
    lbp = (double *)calloc(ncol, sizeof(double));
    ubp = (double *)calloc(ncol, sizeof(double));

    lrp[XPRBgetrownum(*Risk)] = 1;
    for (r = 0; r<NREGIONS; r++) lrp[XPRBgetrownum(MaxReg[r])] = 1;
    for (t = 0; t<NTYPES; t++) lrp[XPRBgetrownum(LimSec[t])] = 1;
    lrp[XPRBgetrownum(*Num)] = 1;
    for (r = 0; r<NREGIONS; r++) grp[XPRBgetrownum(MinReg[r])] = 1;

    for (delta = 0.001; delta < 10; delta *= 10) {
      XPRSrepairweightedinfeas(op, &repstatus, lrp, grp, lbp, ubp, 'r', delta, "");
      printf("delta = %g: Status: %s\n", delta, rstat[repstatus]);
      if (repstatus == 0) {
        XPRBsync(prob, XPRB_XPRS_SOLMIP);
        print_sol_opt();
        print_violated();
      }
    }

    free(lrp);
    free(grp);
    free(lbp);
    free(ubp);
  }

  return 0;
}

/**************************Solution printing****************************/

void print_sol_opt(void)
{
  int s;
  printf("  Total return: %g\n", XPRBgetobjval(prob));
  for (s = 0; s<NSHARES; s++)
    if (XPRBgetsol(buy[s]) > 0.5)
      printf("  %s : %g%% (%g)\n", SHARES_n[s], XPRBgetsol(frac[s])*100, XPRBgetsol(buy[s]));
}

void print_violated(void)
{
  int i;
  char *type=NULL;
  printf(" Violated (relaxed) constraints:\n");
  for (i = 0; i < allCtrCount; i++) {
    double viol, slack = XPRBgetslack(allCtr[i]);
    switch (XPRBgetctrtype(allCtr[i])) {
      case XPRB_E: viol = fabs(slack); type = " ="; break;
      case XPRB_G: viol = slack;       type = ">="; break;
      case XPRB_L: viol = -slack;      type = "<="; break;
      default: printf("  unexpected constraint type\n"); continue;
    }
    if (viol>1e-6) printf("  %s constraint %s by %g\n", type, XPRBgetctrname(allCtr[i]), -slack);
  }
}

© 2001-2020 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.