MIP model 2: imposing a minimum investment in each share
To formulate the second MIP model, we start again with the LP model from Chapters 2 and 3. The new constraint we wish to formulate is `if a share is bought, at least a certain minimum amount MINVAL = 10% of the budget is spent on the share.' Instead of simply constraining every variable fracs to take a value between 0 and MAXVAL, it now must either lie in the interval between MINVAL and MAXVAL or take the value 0. This type of variable is known as semi-continuous variable. In the new model, we replace the bounds on the variables fracs by the following constraint:
Implementation with Mosel
The following model foliomip2.mos implements the MIP model 2, again starting with the LP model from Chapter 3 augmented by the data initialization from file explained in Chapter 4. The semi-continuous variables are defined with the is_semcont constraint.
A similar type is available for integer variables that take either the value 0 or an integer value between a given limit and their upper bound (so-called semi-continuous integers): is_semint. A third composite type is a partial integer which takes integer values from its lower bound to a given limit value and is continuous beyond this value (marked by is_partint).
model "Portfolio optimization with MIP"
 uses "mmxprs"                      ! Use Xpress Optimizer
 parameters
  MAXRISK = 1/3                     ! Max. investment into high-risk values
  MINAM = 0.5                       ! Min. investment into N.-American values
  MAXVAL = 0.3                      ! Max. investment per share
  MINVAL = 0.1                      ! Min. investment per share
 end-parameters
 declarations
  SHARES: set of string             ! Set of shares
  RISK: set of string               ! Set of high-risk values among shares
  NA: set of string                 ! Set of shares issued in N.-America
  RET: array(SHARES) of real        ! Estimated return in investment
 end-declarations
 initializations from "folio.dat"
  RISK RET NA
 end-initializations
 declarations
  frac: array(SHARES) of mpvar      ! Fraction of capital used per share
 end-declarations
! Objective: total return
 Return:= sum(s in SHARES) RET(s)*frac(s)
! Limit the percentage of high-risk values
 sum(s in RISK) frac(s) <= MAXRISK
! Minimum amount of North-American values
 sum(s in NA) frac(s) >= MINAM
! Spend all the capital
 sum(s in SHARES) frac(s) = 1
! Upper and lower bounds on the investment per share
 forall(s in SHARES) do
  frac(s) <= MAXVAL
  frac(s) is_semcont MINVAL
 end-do
! Solve the problem
 maximize(Return)
! Solution printing
 writeln("Total return: ", getobjval)
 forall(s in SHARES) writeln(s, ": ", getsol(frac(s))*100, "%")
end-model When executing this model of the solution information window) we obtain the following output:
Total return: 14.0333 treasury: 30% hardware: 0% theater: 20% telecom: 0% brewery: 10% highways: 26.6667% cars: 0% bank: 0% software: 13.3333% electronics: 0%
Now five securities are chosen for the portfolio, each forming at least 10% and at most 30% of the total investment. Due to the additional constraint, the optimal MIP solution value is again lower than the initial LP solution value.
 
