Initializing help system before first use

Data input from file

Instead of simply numbering the decision variables, we may wish to use more meaningful indices in our model. For instance, the problem data may be given in file(s) using string indices such as the file foliocpplp.dat we now wish to read:

! Return
"treasury" 	5
"hardware" 	17
"theater" 	26
"telecom" 	12
"brewery" 	8
"highways" 	9
"cars" 		7
"bank" 		6
"software" 	31
"electronics" 	21

We modify our previous model as follows to work with this data file:

#include <iostream>
#include "xprb_cpp.h"

using namespace std;
using namespace ::dashoptimization;

#define DATAFILE "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;
}

The arrays RISK and NA now store indices in the form of strings and we have added a new object, the index set SHARES that is defined while the return-on-investment values RET are read from the data file. In this example we have initialized the index set with exactly the right size. This is not really necessary since index sets may grow dynamically if more entries are added to them than the initially allocated space. The actual set size can be obtained with the method getSize.

For reading the data we use the function XPRBreadlinecb. It will skip comments preceded by ! and any empty lines in the data file. The format string "T g" indicates that we wish to read a text string (surrounded by single or double quotes if it contains blanks) followed by a real number, the two separated by spaces (including tabulation). If the data file used another separator sign such as `,' then the format string could be changed accordingly (e.g. "T,g").

In the model itself, the definition of the linear expressions Risk and Na has been adapted to the new indices.

Another modification concerns the solution printing: we print the name of every share, not simply its sequence number and hence the solution now gets displayed as follows:

Total return: 14.0667
treasury: 30%
hardware: 0%
theater: 20%
telecom: 0%
brewery: 6.66667%
highways: 30%
cars: 0%
bank: 0%
software: 13.3333%
electronics: 0%