Folio - Examples from 'Getting Started'
|
|
Type: | Portfolio optimization |
Rating: | 3 (intermediate) |
Description: | Different versions of a portfolio optimization problem. Basic modelling and solving tasks:
|
File(s): | foliolp.cpp, folioinit.cpp, foliodata.cpp, foliomip1.cpp, foliomip2.cpp, folioqp.cpp, folioqc.cpp, folioheur.cpp, foliomip3.cpp, readfoliodata.c_, foliocb.cpp, foliosolpool.cpp, folioenumsol.cpp, folioinfeas.cpp, folioiis.cpp, foliorep.cpp |
Data file(s): | foliocpplp.dat, foliocppqp.dat, folio10.cdat |
|
foliolp.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file foliolp.cpp ```````````````` Modeling a small LP problem to perform portfolio optimization. (c) 2008 Fair Isaac Corporation author: S.Heipcke, Aug. 2003, rev. Mar. 2011 ********************************************************/ #include <iostream> #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; #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 p("FolioLP"); // Initialize a new problem in BCL XPRBexpr Risk,Na,Return,Cap; XPRBvar frac[NSHARES]; // Fraction of capital used per share // Create the decision variables for(s=0;s<NSHARES;s++) frac[s] = p.newVar("frac"); //, XPRB_PL, 0, 0.3); // Objective: total return for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s]; p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values for(s=0;s<NRISK;s++) Risk += frac[RISK[s]]; p.newCtr("Risk", Risk <= 1.0/3); /* Equivalent: XPRBctr CRisk; CRisk = p.newCtr("Risk"); for(s=0;s<NRISK;s++) CRisk.addTerm(frac[RISK[s]], 1); CRisk.setType(XPRB_L); CRisk.addTerm(1.0/3); */ // Minimum amount of North-American values for(s=0;s<NNA;s++) Na += frac[NA[s]]; p.newCtr("NA", Na >= 0.5); // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr("Cap", Cap == 1); // Upper bounds on the investment per share for(s=0;s<NSHARES;s++) frac[s].setUB(0.3); // Export matrix to a file /* p.exportProb(XPRB_MPS, "Folio"); p.setSense(XPRB_MAXIM); p.exportProb(XPRB_LP, "Folio"); */ // Disable all BCL and Optimizer message printing, except error messages // p.setMsgLevel(1); // Solve the problem p.setSense(XPRB_MAXIM); p.lpOptimize(""); char *LPSTATUS[] = {"not loaded", "optimal", "infeasible", "worse than cutoff", "unfinished", "unbounded", "cutoff in dual", "unsolved", "nonconvex"}; cout << "Problem status: " << LPSTATUS[p.getLPStat()] << endl; // Solution printing cout << "Total return: " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) cout << s << ": " << frac[s].getSol()*100 << "%" << endl; return 0; } |
folioinit.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file folioinit.cpp `````````````````` Modeling a small LP problem to perform portfolio optimization. Explicit initialization. (c) 2008 Fair Isaac Corporation author: S.Heipcke, Aug. 2003, rev. Mar. 2011 ********************************************************/ #include <iostream> #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; #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() { int s; XPRBprob p("FolioLP"); // Initialize a new problem in BCL XPRBexpr Risk,Na,Return,Cap; XPRBvar frac[NSHARES]; // Fraction of capital used per share // Create the decision variables for(s=0;s<NSHARES;s++) frac[s] = p.newVar("frac"); // Objective: total return for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s]; p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values for(s=0;s<NRISK;s++) Risk += frac[RISK[s]]; p.newCtr("Risk", Risk <= 1.0/3); // Minimum amount of North-American values for(s=0;s<NNA;s++) Na += frac[NA[s]]; p.newCtr("NA", Na >= 0.5); // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr("Cap", Cap == 1); // Upper bounds on the investment per share for(s=0;s<NSHARES;s++) frac[s].setUB(0.3); // Solve the problem p.setSense(XPRB_MAXIM); p.lpOptimize(""); char *LPSTATUS[] = {"not loaded", "optimal", "infeasible", "worse than cutoff", "unfinished", "unbounded", "cutoff in dual", "unsolved", "nonconvex"}; cout << "Problem status: " << LPSTATUS[p.getLPStat()] << endl; // Solution printing cout << "Total return: " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) cout << s << ": " << frac[s].getSol()*100 << "%" << endl; } int main(int argc, char **argv) { if(XPRB::init() != 0) { cout << "Initialization failed." << endl; return 1; } solveProb(); return 0; } |
foliodata.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file foliodata.cpp `````````````````` Modeling a small LP problem to perform portfolio optimization. -- Data input from file -- (c) 2008 Fair Isaac Corporation author: S.Heipcke, Aug. 2003, rev. Mar. 2011 ********************************************************/ #include <iostream> #include <cstdio> #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; #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 XPRBindexSet SHARES; // Set of shares XPRBprob p("FolioLP"); // Initialize a new problem in BCL void readData(void) { double value; int s; FILE *datafile; char name[100]; SHARES=p.newIndexSet("Shares",NSHARES); // Create the `SHARES' index set // 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[SHARES+=name]=value; } fclose(datafile); SHARES.print(); // Print out the set contents } int main(int argc, char **argv) { int s; XPRBexpr Risk,Na,Return,Cap; XPRBvar frac[NSHARES]; // Fraction of capital used per share // Read data from file readData(); // Create the decision variables for(s=0;s<NSHARES;s++) frac[s] = p.newVar("frac"); // Objective: total return for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s]; p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values for(s=0;s<NRISK;s++) Risk += frac[SHARES[RISK[s]]]; p.newCtr("Risk", Risk <= 1.0/3); // Minimum amount of North-American values for(s=0;s<NNA;s++) Na += frac[SHARES[NA[s]]]; p.newCtr("NA", Na >= 0.5); // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr("Cap", Cap == 1); // Upper bounds on the investment per share for(s=0;s<NSHARES;s++) frac[s].setUB(0.3); // Solve the problem p.setSense(XPRB_MAXIM); p.lpOptimize(""); // Solution printing cout << "Total return: " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) cout << SHARES[s] << ": " << frac[s].getSol()*100 << "%" << endl; return 0; } |
foliomip1.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file foliomip1.cpp `````````````````` Modeling a small MIP problem to perform portfolio optimization. -- Limiting the total number of assets -- (c) 2008 Fair Isaac Corporation author: S.Heipcke, Aug. 2003, rev. Mar. 2011 ********************************************************/ #include <iostream> #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; #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 p("FolioMIP1"); // Initialize a new problem in BCL XPRBexpr 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 // Create the decision variables (including upper bounds for `frac') for(s=0;s<NSHARES;s++) { frac[s] = p.newVar("frac", XPRB_PL, 0, 0.3); buy[s] = p.newVar("buy", XPRB_BV); } // Objective: total return for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s]; p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values for(s=0;s<NRISK;s++) Risk += frac[RISK[s]]; p.newCtr(Risk <= 1.0/3); // Minimum amount of North-American values for(s=0;s<NNA;s++) Na += frac[NA[s]]; p.newCtr(Na >= 0.5); // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr(Cap == 1); // Limit the total number of assets for(s=0;s<NSHARES;s++) Num += buy[s]; p.newCtr(Num <= MAXNUM); // Linking the variables for(s=0;s<NSHARES;s++) p.newCtr(frac[s] <= buy[s]); // Solve the problem p.setSense(XPRB_MAXIM); p.mipOptimize(""); char *MIPSTATUS[] = {"not loaded", "not optimized", "LP optimized", "unfinished (no solution)", "unfinished (solution found)", "infeasible", "optimal", "unbounded"}; cout << "Problem status: " << MIPSTATUS[p.getMIPStat()] << endl; // Solution printing cout << "Total return: " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) cout << s << ": " << frac[s].getSol()*100 << "% (" << buy[s].getSol() << ")" << endl; return 0; } |
foliomip2.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file foliomip2.cpp `````````````````` Modeling a small MIP problem to perform portfolio optimization. -- Imposing a minimum investment per share -- (c) 2008 Fair Isaac Corporation author: S.Heipcke, Aug. 2003, rev. Mar. 2011 ********************************************************/ #include <iostream> #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; #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 p("FolioSC"); // Initialize a new problem in BCL XPRBexpr Risk,Na,Return,Cap; XPRBvar frac[NSHARES]; // Fraction of capital used per share // Create the decision variables for(s=0;s<NSHARES;s++) { frac[s] = p.newVar("frac", XPRB_SC, 0, 0.3); frac[s].setLim(0.1); } // Objective: total return for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s]; p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values for(s=0;s<NRISK;s++) Risk += frac[RISK[s]]; p.newCtr(Risk <= 1.0/3); // Minimum amount of North-American values for(s=0;s<NNA;s++) Na += frac[NA[s]]; p.newCtr(Na >= 0.5); // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr(Cap == 1); // Solve the problem p.setSense(XPRB_MAXIM); p.mipOptimize(""); // Solution printing cout << "Total return: " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) cout << s << ": " << frac[s].getSol()*100 << "%" << endl; return 0; } |
folioqp.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file folioqp.cpp ```````````````` 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, Aug. 2003, rev. Mar. 2011 ********************************************************/ #include <iostream> #include <cstdio> #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; #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 p("FolioQP"); // Initialize a new problem in BCL XPRBexpr Na,Return,Cap,Num,Variance; XPRBvar frac[NSHARES]; // Fraction of capital used per share XPRBvar buy[NSHARES]; // 1 if asset is in portfolio, 0 otherwise FILE *datafile; // 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] = p.newVar(XPRBnewname("frac(%d)",s+1), XPRB_PL, 0, 0.3); // Objective: mean variance for(s=0;s<NSHARES;s++) for(t=0;t<NSHARES;t++) Variance += VAR[s][t]*frac[s]*frac[t]; p.setObj(Variance); // Set the objective function // Minimum amount of North-American values for(s=0;s<NNA;s++) Na += frac[NA[s]]; p.newCtr(Na >= 0.5); // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr(Cap == 1); // Target yield for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s]; p.newCtr(Return >= TARGET); // Solve the problem p.setSense(XPRB_MINIM); p.lpOptimize(""); // Solution printing cout << "With a target of " << TARGET << " minimum variance is " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) cout << s << ": " << frac[s].getSol()*100 << "%" << endl; // **** Second problem: limit total number of assets **** // Create the decision variables for(s=0;s<NSHARES;s++) buy[s] = p.newVar(XPRBnewname("buy(%d)",s+1), XPRB_BV); // Limit the total number of assets for(s=0;s<NSHARES;s++) Num += buy[s]; p.newCtr(Num <= MAXNUM); // Linking the variables for(s=0;s<NSHARES;s++) p.newCtr(frac[s] <= buy[s]); // Solve the problem p.mipOptimize(""); // Solution printing cout << "With a target of " << TARGET << " and at most " << MAXNUM << " assets, minimum variance is " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) cout << s << ": " << frac[s].getSol()*100 << "% (" << buy[s].getSol() << ")" << endl; return 0; } |
folioqc.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file folioqp.cpp ```````````````` 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 <iostream> #include <cstdio> #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; #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 p("FolioQC"); // Initialize a new problem in BCL XPRBexpr Na,Return,Cap,Variance; XPRBvar frac[NSHARES]; // Fraction of capital used per share FILE *datafile; // 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] = p.newVar(XPRBnewname("frac(%d)",s+1), XPRB_PL, 0, 0.3); // Objective: total return for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s]; p.setObj(Return); // Set the objective function // Minimum amount of North-American values for(s=0;s<NNA;s++) Na += frac[NA[s]]; p.newCtr(Na >= 0.5); // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr(Cap == 1); // Limit variance for(s=0;s<NSHARES;s++) for(t=0;t<NSHARES;t++) Variance += VAR[s][t]*frac[s]*frac[t]; p.newCtr(Variance <= MAXVAR); // Solve the problem p.setSense(XPRB_MAXIM); p.lpOptimize(""); // Solution printing cout << "With a max. variance of " << MAXVAR << " total return is " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) cout << s << ": " << frac[s].getSol()*100 << "%" << endl; return 0; } |
folioheur.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file folioheur.cpp `````````````````` Modeling a small MIP problem to perform portfolio optimization. -- Heuristic solution -- (c) 2008 Fair Isaac Corporation author: S.Heipcke, Aug. 2003, rev. Mar. 2011 ********************************************************/ #include <iostream> #include "xprb_cpp.h" #include "xprs.h" using namespace std; using namespace ::dashoptimization; #define MAXNUM 4 // Max. number of shares to be selected #define NSHARES 10 // Number of shares #define NRISK 5 // Number of high-risk shares #define NNA 4 // Number of North-American shares void solveHeur(); 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 p("FolioMIPHeur"); // Initialize a new problem in BCL 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; XPRBexpr Risk,Na,Return,Cap,Num; // Create the decision variables (including upper bounds for `frac') for(s=0;s<NSHARES;s++) { frac[s] = p.newVar("frac", XPRB_PL, 0, 0.3); buy[s] = p.newVar("buy", XPRB_BV); } // Objective: total return for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s]; p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values for(s=0;s<NRISK;s++) Risk += frac[RISK[s]]; p.newCtr(Risk <= 1.0/3); // Minimum amount of North-American values for(s=0;s<NNA;s++) Na += frac[NA[s]]; p.newCtr(Na >= 0.5); // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr(Cap == 1); // Limit the total number of assets for(s=0;s<NSHARES;s++) Num += buy[s]; p.newCtr(Num <= MAXNUM); // Linking the variables for(s=0;s<NSHARES;s++) p.newCtr(frac[s] <= buy[s]); // Solve problem heuristically p.setSense(XPRB_MAXIM); solveHeur(); // Solve the problem p.mipOptimize(""); // Solution printing if(p.getMIPStat()==XPRB_MIP_SOLUTION || p.getMIPStat()==XPRB_MIP_OPTIMAL) { cout << "Exact solution: Total return: " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) cout << s << ": " << frac[s].getSol()*100 << "%" << endl; } else cout << "Heuristic solution is optimal." << endl; return 0; } void solveHeur() { XPRBbasis basis; int s, ifgsol; double solval, fsol[NSHARES],TOL; XPRSsetintcontrol(p.getXPRSprob(), XPRS_CUTSTRATEGY, 0); // Disable automatic cuts XPRSsetintcontrol(p.getXPRSprob(), XPRS_PRESOLVE, 0); // Switch presolve off XPRSgetdblcontrol(p.getXPRSprob(), XPRS_FEASTOL, &TOL); // Get feasibility tolerance p.mipOptimize("l"); // Solve the LP-relaxation basis=p.saveBasis(); // 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]=frac[s].getSol(); // Get the solution values of `frac' if(fsol[s] < TOL) buy[s].setUB(0); else if(fsol[s] > 0.2-TOL) buy[s].setLB(1); } p.mipOptimize("c"); // Solve the MIP-problem ifgsol=0; if(p.getMIPStat()==XPRB_MIP_SOLUTION || p.getMIPStat()==XPRB_MIP_OPTIMAL) { // If an integer feas. solution was found ifgsol=1; solval=p.getObjVal(); // Get the value of the best solution cout << "Heuristic solution: Total return: " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) cout << s << ": " << frac[s].getSol()*100 << "%" << endl; } // XPRSpostsolve(p.getXPRSprob()); // 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)) { buy[s].setLB(0); buy[s].setUB(1); } p.loadBasis(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 */ basis.reset(); // No need to store the saved basis any longer if(ifgsol==1) XPRSsetdblcontrol(p.getXPRSprob(), XPRS_MIPABSCUTOFF, solval+TOL); // Set the cutoff to the best known solution } |
foliomip3.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file foliomip3.cpp `````````````````` 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 <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; #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 **SECT; // 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 p("FolioMIP3"); // Initialize a new problem in BCL XPRBexpr Risk,Return,Cap,Num; XPRBexpr *MinReg, *MaxReg, *LimSec, LinkL, LinkU; XPRBvar *frac; // Fraction of capital used per share XPRBvar *buy; // 1 if asset is in portfolio, 0 otherwise readdata(DATAFILE); // Data input from file // Create the decision variables (including upper bounds for `frac') frac = new XPRBvar[NSHARES]; buy = new XPRBvar[NSHARES]; for(s=0;s<NSHARES;s++) { frac[s] = p.newVar("frac", XPRB_PL, 0, MAXVAL); buy[s] = p.newVar("buy", XPRB_BV); } // Objective: total return for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s]; p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values for(s=0;s<NRISK;s++) Risk += frac[RISK[s]]; p.newCtr(Risk <= MAXRISK); // Limits on geographical distribution MinReg = new XPRBexpr[NREGIONS]; MaxReg = new XPRBexpr[NREGIONS]; for(r=0;r<NREGIONS;r++) { for(s=0;s<NSHARES;s++) if(LOC[r][s]>0) { MinReg[r] += frac[s]; MaxReg[r] += frac[s]; } p.newCtr(MinReg[r] >= MINREG); p.newCtr(MaxReg[r] <= MAXREG); } // Diversification across industry sectors LimSec = new XPRBexpr[NTYPES]; for(t=0;t<NTYPES;t++) { for(s=0;s<NSHARES;s++) if(SECT[t][s]>0) LimSec[t] += frac[s]; p.newCtr(LimSec[t] <= MAXSEC); } // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr(Cap == 1); // Limit the total number of assets for(s=0;s<NSHARES;s++) Num += buy[s]; p.newCtr(Num <= MAXNUM); // Linking the variables for(s=0;s<NSHARES;s++) { p.newCtr(frac[s] <= MAXVAL*buy[s]); p.newCtr(frac[s] >= MINVAL*buy[s]); } // Solve the problem p.setSense(XPRB_MAXIM); p.mipOptimize(""); char *MIPSTATUS[] = {"not loaded", "not optimized", "LP optimized", "unfinished (no solution)", "unfinished (solution found)", "infeasible", "optimal", "unbounded"}; cout << "Problem status: " << MIPSTATUS[p.getMIPStat()] << endl; // Solution printing cout << "Total return: " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) if(buy[s].getSol()>0.5) cout << SHARES_n[s] << ": " << frac[s].getSol()*100 << "% (" << buy[s].getSol() << ")" << endl; 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,®IONS_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,&SECT,NTYPES,NSHARES); else break; } fclose(f); return NSHARES<1 || NRISK<1 || NREGIONS<1 || NTYPES<1 || RET==NULL || RISK==NULL || LOC==NULL || SECT==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("SECT:"); for(i=0;i<NTYPES;i++) { for(j=0;j<NSHARES;j++) printf(" %d",SECT[i][j]); printf("\n"); } } |
foliocb.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file foliocb.cpp ```````````````` Modeling a MIP problem to perform portfolio optimization. Same model as in foliomip3.cpp. -- Defining an integer solution callback -- (c) 2009 Fair Isaac Corporation author: S.Heipcke, May 2009, rev. Mar. 2011 ********************************************************/ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include "xprb_cpp.h" #include "xprs.h" using namespace std; using namespace ::dashoptimization; #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 **SECT; // 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 p("FolioMIP3"); // Initialize a new problem in BCL XPRBexpr Risk,Return,Cap,Num; XPRBexpr *MinReg, *MaxReg, *LimSec, LinkL, LinkU; readdata(DATAFILE); // Data input from file // Create the decision variables (including upper bounds for `frac') frac = new XPRBvar[NSHARES]; buy = new XPRBvar[NSHARES]; for(s=0;s<NSHARES;s++) { frac[s] = p.newVar("frac", XPRB_PL, 0, MAXVAL); buy[s] = p.newVar("buy", XPRB_BV); } // Objective: total return for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s]; p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values for(s=0;s<NRISK;s++) Risk += frac[RISK[s]]; p.newCtr(Risk <= MAXRISK); // Limits on geographical distribution MinReg = new XPRBexpr[NREGIONS]; MaxReg = new XPRBexpr[NREGIONS]; for(r=0;r<NREGIONS;r++) { for(s=0;s<NSHARES;s++) if(LOC[r][s]>0) { MinReg[r] += frac[s]; MaxReg[r] += frac[s]; } p.newCtr(MinReg[r] >= MINREG); p.newCtr(MaxReg[r] <= MAXREG); } // Diversification across industry sectors LimSec = new XPRBexpr[NTYPES]; for(t=0;t<NTYPES;t++) { for(s=0;s<NSHARES;s++) if(SECT[t][s]>0) LimSec[t] += frac[s]; p.newCtr(LimSec[t] <= MAXSEC); } // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr(Cap == 1); // Limit the total number of assets for(s=0;s<NSHARES;s++) Num += buy[s]; p.newCtr(Num <= MAXNUM); // Linking the variables for(s=0;s<NSHARES;s++) { p.newCtr(frac[s] <= MAXVAL*buy[s]); p.newCtr(frac[s] >= MINVAL*buy[s]); } // Define an integer solution callback XPRSsetcbintsol(p.getXPRSprob(), print_sol, &p); // Solve the problem p.setSense(XPRB_MAXIM); p.mipOptimize(""); char *MIPSTATUS[] = {"not loaded", "not optimized", "LP optimized", "unfinished (no solution)", "unfinished (solution found)", "infeasible", "optimal", "unbounded"}; cout << "Problem status: " << MIPSTATUS[p.getMIPStat()] << endl; return 0; } /**************************Solution printing****************************/ void XPRS_CC print_sol(XPRSprob oprob, void *vp) { int num,s; XPRBprob *bprob; bprob = (XPRBprob *)vp; bprob->beginCB(oprob); XPRSgetintattrib(oprob, XPRS_MIPSOLS, &num); // Get number of the solution bprob->sync(XPRB_XPRS_SOL); // Update BCL solution values cout << "Solution " << num << ": Total return: " << bprob->getObjVal() << endl; for(s=0;s<NSHARES;s++) if(buy[s].getSol()>0.5) cout << " " << SHARES_n[s] << ": " << frac[s].getSol()*100 << "% (" << buy[s].getSol() << ")" << endl; bprob->endCB(); } |
foliosolpool.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file foliosolpool.cpp ``````````````````` Modeling a MIP problem to perform portfolio optimization. Same model as in foliomip3.cpp. -- Using the MIP solution pool -- (c) 2009 Fair Isaac Corporation author: S.Heipcke, May 2009, rev. Mar. 2011 ********************************************************/ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include "xprb_cpp.h" #include "xprs.h" using namespace std; using namespace ::dashoptimization; #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 **SECT; // 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 XPRBctr Return; #include "readfoliodata.c_" void print_sol(int num); int main(int argc, char **argv) { int s,r,t; XPRBprob p("FolioMIP3"); // Initialize a new problem in BCL XPRBexpr Risk,Cap,Num,le; XPRBexpr *MinReg, *MaxReg, *LimSec, LinkL, LinkU; readdata(DATAFILE); // Data input from file // Create the decision variables (including upper bounds for `frac') frac = new XPRBvar[NSHARES]; buy = new XPRBvar[NSHARES]; for(s=0;s<NSHARES;s++) { frac[s] = p.newVar("frac", XPRB_PL, 0, MAXVAL); buy[s] = p.newVar("buy", XPRB_BV); } // Objective: total return for(s=0;s<NSHARES;s++) le += RET[s]*frac[s]; Return = p.newCtr(le); p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values for(s=0;s<NRISK;s++) Risk += frac[RISK[s]]; p.newCtr(Risk <= MAXRISK); // Limits on geographical distribution MinReg = new XPRBexpr[NREGIONS]; MaxReg = new XPRBexpr[NREGIONS]; for(r=0;r<NREGIONS;r++) { for(s=0;s<NSHARES;s++) if(LOC[r][s]>0) { MinReg[r] += frac[s]; MaxReg[r] += frac[s]; } p.newCtr(MinReg[r] >= MINREG); p.newCtr(MaxReg[r] <= MAXREG); } // Diversification across industry sectors LimSec = new XPRBexpr[NTYPES]; for(t=0;t<NTYPES;t++) { for(s=0;s<NSHARES;s++) if(SECT[t][s]>0) LimSec[t] += frac[s]; p.newCtr(LimSec[t] <= MAXSEC); } // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr(Cap == 1); // Limit the total number of assets for(s=0;s<NSHARES;s++) Num += buy[s]; p.newCtr(Num <= MAXNUM); // Linking the variables for(s=0;s<NSHARES;s++) { p.newCtr(frac[s] <= MAXVAL*buy[s]); p.newCtr(frac[s] >= MINVAL*buy[s]); } // Create a MIP solution pool and attach it to the problem // (so it collects the solutions) XPRSmipsolpool msp; XPRS_msp_create(&msp); XPRS_msp_probattach(msp, p.getXPRSprob()); // Avoid storing of duplicate solutions (3: compare discrete variables only) XPRS_msp_setintcontrol(msp, XPRS_MSP_DUPLICATESOLUTIONSPOLICY, 3); // Solve the problem p.setSense(XPRB_MAXIM); p.mipOptimize(""); // Setup some resources to iterate through the solutions stored // in the MIP solution pool int nSols, nCols, i; double *xsol; int *solIDs; XPRSgetintattrib(p.getXPRSprob(), 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, p.getXPRSprob(), 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); p.loadMIPSol(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; cout << "Solution " << num << ": Total return: " << Return.getAct() << endl; for(s=0;s<NSHARES;s++) if(buy[s].getSol()>0.5) cout << " " << SHARES_n[s] << ": " << frac[s].getSol()*100 << "% (" << buy[s].getSol() << ")" << endl; } |
folioenumsol.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file folioenumsol.cpp ````````````````````` Modeling a MIP problem to perform portfolio optimization. Same model as in foliomip3.cpp. -- Using the solution enumerator -- (c) 2009 Fair Isaac Corporation author: S.Heipcke, June 2009, rev. Jul. 2014 ********************************************************/ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include "xprb_cpp.h" #include "xprs.h" #include "xprs_mse_defaulthandler.h" using namespace std; using namespace ::dashoptimization; #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 **SECT; // 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 XPRBctr Return; #include "readfoliodata.c_" void print_sol(int num); int main(int argc, char **argv) { int s,r,t; XPRBprob p("FolioMIP3"); // Initialize a new problem in BCL XPRBexpr Risk,Cap,Num,le; XPRBexpr *MinReg, *MaxReg, *LimSec, LinkL, LinkU; readdata(DATAFILE); // Data input from file // Create the decision variables (including upper bounds for `frac') frac = new XPRBvar[NSHARES]; buy = new XPRBvar[NSHARES]; for(s=0;s<NSHARES;s++) { frac[s] = p.newVar("frac", XPRB_PL, 0, MAXVAL); buy[s] = p.newVar("buy", XPRB_BV); } // Objective: total return for(s=0;s<NSHARES;s++) le += RET[s]*frac[s]; Return = p.newCtr(le); p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values for(s=0;s<NRISK;s++) Risk += frac[RISK[s]]; p.newCtr(Risk <= MAXRISK); // Limits on geographical distribution MinReg = new XPRBexpr[NREGIONS]; MaxReg = new XPRBexpr[NREGIONS]; for(r=0;r<NREGIONS;r++) { for(s=0;s<NSHARES;s++) if(LOC[r][s]>0) { MinReg[r] += frac[s]; MaxReg[r] += frac[s]; } p.newCtr(MinReg[r] >= MINREG); p.newCtr(MaxReg[r] <= MAXREG); } // Diversification across industry sectors LimSec = new XPRBexpr[NTYPES]; for(t=0;t<NTYPES;t++) { for(s=0;s<NSHARES;s++) if(SECT[t][s]>0) LimSec[t] += frac[s]; p.newCtr(LimSec[t] <= MAXSEC); } // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr(Cap == 1); // Limit the total number of assets for(s=0;s<NSHARES;s++) Num += buy[s]; p.newCtr(Num <= MAXNUM); // Linking the variables for(s=0;s<NSHARES;s++) { p.newCtr(frac[s] <= MAXVAL*buy[s]); p.newCtr(frac[s] >= MINVAL*buy[s]); } // Create a MIP solution pool & enumerator XPRSmipsolpool msp; XPRSmipsolenum mse; XPRS_mse_create(&mse); XPRS_msp_create(&msp); // Load matrix into the Optimizer, then hand over to sol. enumerator p.loadMat(); // Disable heuristics to avoid duplicate solutions being stored XPRSsetintcontrol(p.getXPRSprob(), XPRS_HEURSTRATEGY, 0); int nMaxSols = 15; // Max. number of solutions to return // Solve the problem XPRS_mse_maxim(mse, p.getXPRSprob(), msp, XPRS_mse_defaulthandler, NULL, &nMaxSols); // Setup some resources to iterate through the solutions stored // in the MIP solution pool int nSols, nCols, i; double *xsol; int *solIDs; XPRSgetintattrib(p.getXPRSprob(), 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); p.loadMIPSol(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; cout << "Solution " << num << ": Total return: " << Return.getAct() << endl; for(s=0;s<NSHARES;s++) if(buy[s].getSol()>0.5) cout << " " << SHARES_n[s] << ": " << frac[s].getSol()*100 << "% (" << buy[s].getSol() << ")" << endl; } |
folioinfeas.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file folioinfeas.cpp ```````````````````` Modeling a MIP problem to perform portfolio optimization. Same model as in foliomip3.cpp. -- Infeasible model parameter values -- -- Handling infeasibility through auxiliary variables -- (c) 2009 Fair Isaac Corporation author: S.Heipcke, June 2009, rev. Mar. 2011 ********************************************************/ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; #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 **SECT; // 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 p("FolioMIP3"); // Initialize a new problem in BCL XPRBctr Risk,Return,Num,*MinReg, *MaxReg, *LimSec; XPRBexpr le, le2, Cap, LinkL, LinkU; XPRBvar *frac; // Fraction of capital used per share XPRBvar *buy; // 1 if asset is in portfolio, 0 otherwise readdata(DATAFILE); // Data input from file // Create the decision variables (including upper bounds for `frac') frac = new XPRBvar[NSHARES]; buy = new XPRBvar[NSHARES]; for(s=0;s<NSHARES;s++) { frac[s] = p.newVar("frac", XPRB_PL, 0, MAXVAL); buy[s] = p.newVar("buy", XPRB_BV); } // Objective: total return for(s=0;s<NSHARES;s++) le += RET[s]*frac[s]; Return = p.newCtr(le); p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values le=0; for(s=0;s<NRISK;s++) le += frac[RISK[s]]; Risk = p.newCtr(le <= MAXRISK); // Limits on geographical distribution MinReg = new XPRBctr[NREGIONS]; MaxReg = new XPRBctr[NREGIONS]; for(r=0;r<NREGIONS;r++) { le=0; le2=0; for(s=0;s<NSHARES;s++) if(LOC[r][s]>0) { le += frac[s]; le2 += frac[s]; } MinReg[r] = p.newCtr(le >= MINREG); MaxReg[r] = p.newCtr(le2 <= MAXREG); } // Diversification across industry sectors LimSec = new XPRBctr[NTYPES]; for(t=0;t<NTYPES;t++) { le=0; for(s=0;s<NSHARES;s++) if(SECT[t][s]>0) le += frac[s]; LimSec[t] = p.newCtr(le <= MAXSEC); } // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr(Cap == 1); // Limit the total number of assets le=0; for(s=0;s<NSHARES;s++) le += buy[s]; Num = p.newCtr(le <= MAXNUM); // Linking the variables for(s=0;s<NSHARES;s++) { p.newCtr(frac[s] <= MAXVAL*buy[s]); p.newCtr(frac[s] >= MINVAL*buy[s]); } // Solve the problem p.setSense(XPRB_MAXIM); p.mipOptimize(""); char *MIPSTATUS[] = {"not loaded", "not optimized", "LP optimized", "unfinished (no solution)", "unfinished (solution found)", "infeasible", "optimal", "unbounded"}; cout << "Problem status: " << MIPSTATUS[p.getMIPStat()] << endl; if (p.getMIPStat()==XPRB_MIP_INFEAS) { cout << "Original problem infeasible. Adding deviation variables" << endl; // Define deviation variables and add them to the constraints // to make problem solvable */ XPRBvar devRisk, devNum, *devMinReg, *devMaxReg, *devSec; devRisk = p.newVar("devRisk"); Risk -= devRisk; devMinReg = new XPRBvar[NREGIONS]; devMaxReg = new XPRBvar[NREGIONS]; for(r=0;r<NREGIONS;r++) { /* Only allow small deviations */ devMinReg[r] = p.newVar("devMinReg", XPRB_PL, 0, MAXREG/2); MinReg[r] += devMinReg[r]; devMaxReg[r] = p.newVar("devMaxReg", XPRB_PL, 0, MAXREG/2); MaxReg[r] -= devMaxReg[r]; } devSec = new XPRBvar[NTYPES]; for(t=0;t<NTYPES;t++) { devSec[t] = p.newVar("devSec", XPRB_PL, 0, MAXSEC/2); LimSec[t] -= devSec[t]; } devNum = p.newVar("devNum", XPRB_PL, 0, XPRB_INFINITY); Num -= devNum; /* Resolve the problem with penalty terms added to the objective */ double penalty = -10; Return += devRisk * penalty; for(r=0;r<NREGIONS;r++) Return += (devMinReg[r]+devMaxReg[r]) * penalty; for(t=0;t<NTYPES;t++) Return += devSec[t] * penalty; Return += devNum * penalty; p.setObj(Return); /* Set the new objective function */ p.mipOptimize(""); if (p.getMIPStat()== XPRB_MIP_INFEAS) { cout << "No solution after relaxation" << endl; return 0; } else { cout << "Constraint violations:" << endl; cout << " Constraint Activity Deviation Bound(s)" << endl; printf(" Risk %1.2f\t %1.2f\t (%1.2f)\n", Risk.getAct()+devRisk.getSol(), devRisk.getSol(), MAXRISK); for(r=0;r<NREGIONS;r++) { double sumf=0; for(s=0;s<NSHARES;s++) if(LOC[r][s]>0) sumf+=frac[s].getSol(); printf(" Region %-11s %1.2f\t %1.2f\t (%g-%g)\n", REGIONS_n[r], sumf, devMaxReg[r].getSol()-devMinReg[r].getSol(), MINREG, MAXREG); } for(t=0;t<NTYPES;t++) { printf(" Sector %-14s %1.2f\t %1.2f\t (%g)\n", TYPES_n[t], LimSec[t].getAct()+devSec[t].getSol(), devSec[t].getSol(), MAXSEC); } printf(" Number of assets %1.2f\t %1.2f\t (%d)\n", Num.getAct()+devNum.getSol(), devNum.getSol(), MAXNUM); } } // Solution printing cout << "Total return: " << p.getObjVal() << endl; for(s=0;s<NSHARES;s++) if(buy[s].getSol()>0.5) cout << SHARES_n[s] << ": " << frac[s].getSol()*100 << "% (" << buy[s].getSol() << ")" << endl; return 0; } |
folioiis.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file folioiis.cpp ````````````````` Modeling a MIP problem to perform portfolio optimization. Same model as in foliomip3.cpp. -- Infeasible model parameter values -- -- Retrieving IIS -- (c) 2009 Fair Isaac Corporation author: S.Heipcke, June 2009, rev. Mar. 2011 ********************************************************/ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include "xprb_cpp.h" #include "xprs.h" using namespace std; using namespace ::dashoptimization; #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 **SECT; // 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 p("FolioMIP3inf"); // Initialize a new problem in BCL XPRBctr Risk,Return,Num,*MinReg, *MaxReg, *LimSec; XPRBexpr le, le2, Cap, LinkL, LinkU; XPRBvar *frac; // Fraction of capital used per share XPRBvar *buy; // 1 if asset is in portfolio, 0 otherwise readdata(DATAFILE); // Data input from file // Create the decision variables (including upper bounds for `frac') frac = new XPRBvar[NSHARES]; buy = new XPRBvar[NSHARES]; for(s=0;s<NSHARES;s++) { frac[s] = p.newVar("frac", XPRB_PL, 0, MAXVAL); buy[s] = p.newVar("buy", XPRB_BV); } // Objective: total return for(s=0;s<NSHARES;s++) le += RET[s]*frac[s]; Return = p.newCtr(le); p.setObj(Return); // Set the objective function // Limit the percentage of high-risk values le=0; for(s=0;s<NRISK;s++) le += frac[RISK[s]]; Risk = p.newCtr("Risk", le <= MAXRISK); // Limits on geographical distribution MinReg = new XPRBctr[NREGIONS]; MaxReg = new XPRBctr[NREGIONS]; for(r=0;r<NREGIONS;r++) { le=0; le2=0; for(s=0;s<NSHARES;s++) if(LOC[r][s]>0) { le += frac[s]; le2 += frac[s]; } MinReg[r] = p.newCtr(XPRBnewname("MinReg(%s)",REGIONS_n[r]), le >= MINREG); MaxReg[r] = p.newCtr(XPRBnewname("MaxReg(%s)",REGIONS_n[r]), le2 <= MAXREG); } // Diversification across industry sectors LimSec = new XPRBctr[NTYPES]; for(t=0;t<NTYPES;t++) { le=0; for(s=0;s<NSHARES;s++) if(SECT[t][s]>0) le += frac[s]; LimSec[t] = p.newCtr(XPRBnewname("LimSec(%s)",TYPES_n[t]), le <= MAXSEC); } // Spend all the capital for(s=0;s<NSHARES;s++) Cap += frac[s]; p.newCtr("Cap", Cap == 1); // Limit the total number of assets le=0; for(s=0;s<NSHARES;s++) le += buy[s]; Num = p.newCtr("Num", le <= MAXNUM); // Linking the variables for(s=0;s<NSHARES;s++) { p.newCtr(frac[s] <= MAXVAL*buy[s]); p.newCtr(frac[s] >= MINVAL*buy[s]); } // Solve the problem (LP) p.setSense(XPRB_MAXIM); p.lpOptimize(""); if (p.getLPStat()==XPRB_LP_INFEAS) { cout << "LP infeasible. Retrieving IIS." << endl; int numiis = p.getNumIIS(); // Get the number of independent IIS cout << "Number of IIS: " << numiis << endl; XPRSprob op = p.getXPRSprob(); // Retrieve the Optimizer problem /**** Obtain variable and constraint names for use in printout ****/ int ncol, nrow, len, numc, numv, i; char *vnames, *cnames; int *viis,*ciis; char **vindex,**cindex; // Retrieve variable names XPRSgetintattrib(op, XPRS_ORIGINALCOLS, &ncol); XPRSgetnamelist(op, 2, NULL, 0, &len, 0, ncol-1); // Get number of bytes required for retrieving names vnames = new char[len]; vindex = new char*[ncol]; XPRSgetnamelist(op, 2, vnames, len, NULL, 0, ncol-1); vindex[0]=vnames; for(i=1; i<ncol; i++) vindex[i] =vindex[i-1]+strlen(vindex[i-1])+1; // Retrieve constraint names XPRSgetintattrib(op, XPRS_ORIGINALROWS, &nrow); XPRSgetnamelist(op, 1, NULL, 0, &len, 0, nrow-1); cnames = new char[len]; cindex = new char*[nrow]; XPRSgetnamelist(op, 1, cnames, len, NULL, 0, nrow-1); cindex[0]=cnames; for(i=1; i<nrow; i++) cindex[i] =cindex[i-1]+strlen(cindex[i-1])+1; /**** Retrieve variables and constraints contained in IIS ****/ for(s=1;s<=numiis;s++) { XPRSgetiisdata(op, s, &numc, &numv, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ciis = new int[numc]; viis = new int[numv]; XPRSgetiisdata(op, s, &numc, &numv, ciis, viis, NULL, NULL, NULL, NULL, NULL, NULL); cout << "IIS " << s << ": " << numv << " variables, "; cout << numc << " constraints" << endl; if (numv>0) { cout << " Variables: "; // Print all variables in the IIS for(i=0;i<numv;i++) cout << vindex[viis[i]] << " "; cout << endl; delete [] viis; // Free the array of variables } if (numc>0) { cout << " Constraints: "; // Print all constraints in the IIS for(i=0;i<numc;i++) cout << cindex[ciis[i]] << " "; cout << endl; delete [] ciis; // Free the array of constraints } } delete [] vnames; delete [] cnames; delete [] vindex; delete [] cindex; } return 0; } |
foliorep.cpp |
/******************************************************** Xpress-BCL C++ Example Problems =============================== file foliorep.cpp ````````````````` Modeling a MIP problem to perform portfolio optimization. Same model as in foliomip3.cpp. -- Infeasible model parameter values -- -- Repairing infeasibilities -- (c) 2009 Fair Isaac Corporation author: S.Heipcke, June 2009, rev. Mar. 2011 ********************************************************/ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <vector> #include "xprb_cpp.h" #include "xprs.h" using namespace std; using namespace ::dashoptimization; #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 **SECT; // 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 print_sol_opt(XPRBprob &p); void print_violated(vector<XPRBctr> &ctrs); int main(int argc, char **argv) { int s, r, t; XPRBprob p("FolioMIP3inf"); // Initialize a new problem in BCL XPRBctr Return, *Risk, *Num, *MinReg, *MaxReg, *LimSec; XPRBexpr le, le2, Cap, LinkL, LinkU; readdata(DATAFILE); // Data input from file // Create the decision variables (including upper bounds for `frac') frac = new XPRBvar[NSHARES]; buy = new XPRBvar[NSHARES]; for (s = 0; s<NSHARES; s++) { frac[s] = p.newVar("frac", XPRB_PL, 0, MAXVAL); buy[s] = p.newVar("buy", XPRB_BV); } // Objective: total return for (s = 0; s<NSHARES; s++) le += RET[s] * frac[s]; Return = p.newCtr(le); p.setObj(Return); // Set the objective function // allocate memory for all constraints: Risk(1), Num(1), MinReg(NREGIONS), MaxReg(NREGIONS), LimSec(NTYPES) vector<XPRBctr> allCtr(2 + 2 * NREGIONS + NTYPES); int allCtrCount = 0; /* init constraint pointers */ Risk = &allCtr[allCtrCount++]; Num = &allCtr[allCtrCount++]; MinReg = &allCtr[allCtrCount]; allCtrCount += NREGIONS; MaxReg = &allCtr[allCtrCount]; allCtrCount += NREGIONS; LimSec = &allCtr[allCtrCount]; allCtrCount += NTYPES; // Limit the percentage of high-risk values le = 0; for (s = 0; s<NRISK; s++) le += frac[RISK[s]]; *Risk = p.newCtr("Risk", le <= MAXRISK); // Limits on geographical distribution for (r = 0; r<NREGIONS; r++) { le = 0; le2 = 0; for (s = 0; s<NSHARES; s++) if (LOC[r][s]>0) { le += frac[s]; le2 += frac[s]; } MinReg[r] = p.newCtr(XPRBnewname("MinReg(%s)", REGIONS_n[r]), le >= MINREG); MaxReg[r] = p.newCtr(XPRBnewname("MaxReg(%s)", REGIONS_n[r]), le2 <= MAXREG); } // Diversification across industry sectors for (t = 0; t<NTYPES; t++) { le = 0; for (s = 0; s<NSHARES; s++) if (SECT[t][s]>0) le += frac[s]; LimSec[t] = p.newCtr(XPRBnewname("LimSec(%s)", TYPES_n[t]), le <= MAXSEC); } // Spend all the capital for (s = 0; s<NSHARES; s++) Cap += frac[s]; p.newCtr("Cap", Cap == 1); // Limit the total number of assets le = 0; for (s = 0; s<NSHARES; s++) le += buy[s]; *Num = p.newCtr("Num", le <= MAXNUM); // Linking the variables for (s = 0; s<NSHARES; s++) { p.newCtr(frac[s] <= MAXVAL*buy[s]); p.newCtr(frac[s] >= MINVAL*buy[s]); } // Solve the problem (LP) p.setMsgLevel(1); p.setSense(XPRB_MAXIM); p.lpOptimize(""); if (p.getLPStat() == XPRB_LP_INFEAS) { cout << "LP infeasible. Start infeasibility repair." << endl; XPRSprob op = p.getXPRSprob(); // 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 */ int ncol, nrow, repstatus; double *lrp, *grp, *lbp, *ubp; XPRSgetintattrib(op, XPRS_ORIGINALCOLS, &ncol); XPRSgetintattrib(op, XPRS_ORIGINALROWS, &nrow); lrp = new double[nrow]; grp = new double[nrow]; lbp = new double[ncol]; ubp = new double[ncol]; memset(lrp, 0, nrow*sizeof(double)); memset(grp, 0, nrow*sizeof(double)); memset(lbp, 0, ncol*sizeof(double)); memset(ubp, 0, ncol*sizeof(double)); lrp[Risk->getRowNum()] = 1; for (r = 0; r<NREGIONS; r++) lrp[MaxReg[r].getRowNum()] = 1; for (t = 0; t<NTYPES; t++) lrp[LimSec[t].getRowNum()] = 1; lrp[Num->getRowNum()] = 1; for (r = 0; r<NREGIONS; r++) grp[MinReg[r].getRowNum()] = 1; char *rstat[] = { "relaxed optimum found", "relaxed problem infeasible", "relaxed problem unbounded", "solution nonoptimal for original objective", "error", "numerical instability" }; for (double delta = 0.001; delta < 10; delta *= 10) { XPRSrepairweightedinfeas(op, &repstatus, lrp, grp, lbp, ubp, 'd', delta, ""); cout << "delta = " << delta << ": Status: " << rstat[repstatus] << endl; if (repstatus == 0) { p.sync(XPRB_XPRS_SOLMIP); print_sol_opt(p); print_violated(allCtr); } } delete[] lrp; delete[] grp; delete[] lbp; delete[] ubp; } return 0; } void print_sol_opt(XPRBprob &p) { cout << " Total return: " << p.getObjVal() << endl; for (int s = 0; s<NSHARES; s++) if (buy[s].getSol() > 0.5) cout << " " << SHARES_n[s] << " : " << frac[s].getSol() * 100 << "% (" << buy[s].getSol() << ")" << endl; } void print_violated(vector<XPRBctr> &ctrs) { char *type = NULL; cout << " Violated (relaxed) constraints:" << endl; for (vector<XPRBctr>::iterator c = ctrs.begin(); c != ctrs.end(); c++) { double viol, slack = c->getSlack(); switch (c->getType()) { case XPRB_E: viol = abs(slack); type = " ="; break; case XPRB_G: viol = slack; type = ">="; break; case XPRB_L: viol = -slack; type = "<="; break; default: cout << " unexpected constraint type" << endl; continue; } if (viol > 1e-6) cout << " " << type << " constraint " << c->getName() << " by " << -slack << endl; } } |
© 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.