(!******************************************************
   Mosel Example Problems
   ======================

   file h6expand.mos
   `````````````````
   Planning the expansion of a company
  
   A company aims to expand and has a series of candidate 
   projects for a planning horizon of five years. Every 
   project has an annual cost and expected benefit after 
   five years. The forecast annual costs of the projects 
   for the next five years as well as the available yearly 
   funds are known. Which project(s) should the company 
   choose now to maximize the total benefit after five years?
   
   A simple IP model with binary decision variables is 
   implemented. For each period, we ensure that the 
   annual cost of the project is at most the available 
   funds for the specific year. The problem solving is
   started repeatedly, initially solving only the root 
   LP relaxation.

   (c) 2008-2022 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002, rev. Mar. 2022
*******************************************************!)

model "H-6 Expansion"
 uses "mmxprs"

 forward procedure printsol

 declarations
  PROJECTS = 1..5                     ! Set of possible projects
  TIME = 1..5                         ! Planning period
  
  COST: array(PROJECTS,TIME) of real  ! Annual costs of projects
  CAP: array(TIME) of real            ! Annually available capital
  RET: array(PROJECTS) of real        ! Estimated profits
  DESCR: array(PROJECTS) of string    ! Description of projects
   
  choose: array(PROJECTS) of mpvar    ! 1 if project is chosen, 0 otherwise
 end-declarations

 initializations from 'h6expand.dat'
  COST CAP RET DESCR
 end-initializations

! Objective: Total profit
 Profit:= sum(p in PROJECTS) RET(p)*choose(p)
 
! Limit on capital availability
 forall(t in TIME) sum(p  in PROJECTS) COST(p,t)*choose(p) <= CAP(t)  

 forall(p in PROJECTS) choose(p) is_binary 
 
! Solve the problem
 maximize(XPRS_LIN, Profit)
 write("LP solution: ")
 printsol

 maximize(Profit)
 write("MIP solution: ")
 printsol
 
! Force acceptance of project 1 (='rounding' of an almost integer LP solution value)
 choose(1)=1 

 maximize(Profit)
 write("Forcing project 1 (", DESCR(1), "): ")
 printsol
 
!-----------------------------------------------------------------

! Solution printing
 procedure printsol
  writeln("Total profit: ", getobjval)
  forall(p in PROJECTS | getsol(choose(p))>0) 
   writeln(" ", DESCR(p), " (", getsol(choose(p)), ")")
 end-procedure
 
end-model
