(!******************************************************
   Mosel Example Problems
   ======================

   file h1loan.mos
   ```````````````
   Choice of loans

   A chain of shops aims to open three new shops located in 
   different cities. An associated opening cost with each 
   shop is given. To finance this project, the company can 
   get loans from three different banks which offer a maximum 
   loan amount and different rates for the different shop 
   projects. To minimize the company's total cost, how much
   money should be borrowed from each bank to finance 
   each shop?

   This LP model minimizes the sum of annual interest payments
   that the company must make. A set of constraints ensures that
   the borrowed amount for each shop is equal to its opening 
   cost. Another set of constraints guarantees, for each bank, 
   that the company borrows at most the maximum loan amount 
   offered by the bank.

   (c) 2008-2022 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002, rev. Mar. 2022
*******************************************************!)

model "H-1 Loan choice"
 uses "mmxprs"

 declarations
  BANKS = 1..3                         ! Set of banks
  SHOPS = {"London", "Munich", "Rome"} ! Set of shops
  DUR: integer                         ! Duration of loans
  
  PRICE: array(SHOPS) of integer       ! Price of shops
  RATE: array(BANKS,SHOPS) of real     ! Interest rates offered by banks
  VMAX: integer                        ! Maximum loan volume per bank
  
  borrow: array(BANKS,SHOPS) of mpvar  ! Loan taken from banks per project
 end-declarations

 initializations from 'h1loan.dat'
  PRICE RATE VMAX DUR
 end-initializations

! Objective: interest payments
 Interest:= 
  sum(b in BANKS, s in SHOPS) borrow(b,s)*RATE(b,s)/(1-(1+RATE(b,s))^(-DUR))

! Finance all projects
 forall(s in SHOPS) sum(b in BANKS) borrow(b,s) = PRICE(s)
 
! Keep within maximum loan volume per bank
 forall(b in BANKS) sum(s in SHOPS) borrow(b,s) <= VMAX 

! Solve the problem
 minimize(Interest)
 
! Solution printing
 writeln("Total interest: ", getobjval)
 forall(s in SHOPS) do
  write("Shop in ", s, ": ")
  forall(b in BANKS | getsol(borrow(b,s))>0) 
   write(" bank ", b, ": ", getsol(borrow(b,s))/1000000, " million")
  writeln
 end-do  
 
end-model
