Linear programming
1. Introduction to linear programming
1.1 Case study
M&D Chemicals produces two products that are sold as raw
materials to companies manufacturing bath soaps and laundry detergents.
Based on an analysis of current inventory levels and potential demand
for the coming month, M&D’s management specified that the combined
production for products A and B must total at least 350 gallons.
Separately, a major customer’s order for 125 gallons of product A
must also be satisfied.
Product A requires 2 hours of processing time per gallon and product
B requires 1 hour of processing time per gallon.
For the coming month, 600 hours of processing time are
available.
M&D’s objective is to satisfy these requirements at a minimum
total production cost.
Production costs are $2 per gallon for product A and $3 per gallon
for product B.
Problem: the company should produce how many products of A
and B to meet the above requests and constraints with a minimum
cost.
1.2 Problem formulation
1.What are decision variables need to be
solved?
Denote that: x_A and x_B is the optimal gallons of product A and product B, respectively.
2.What is the objective function to optimize?
The production costs are defined: \[ 2x_A + 3X_B \]
Because the problem need to solve is optimization the number of products A and B with a minimum cost. Then, the object function is:
\[ Minimize \ 2x_A + 3x_B \]
3.What are constraints?
For the first constraint, the total products A and products B is at least 350 gallons, which is specified by managers.
\[ x_A + x_B \geq 350 \]
Then for the second constraint, major customer’s demand is satisfied that 150 gallons of Product A. \[ x_A \geq 350 \]
In addition, the process time per gallon are required 2 hours and 3 hours for Product A and Product B, respectively. The available processing time must not exceed 600 hours. The third constraint is determined: \[ 2x_A +3x_B \leq 600 \]
Of course that both of product A and B are also non-negative. \[x_A \geq 0, x_B \geq 0\]
4.How do we find the solution analytically?
First of all, we obtain all the constraints, the linear programing can be written as:
\[ Minimize \ 2x_A + 3x_B \]
\[ s.t \ x_A \geq 350 \] \[ x_A + x_B \geq 350 \] \[ 2x_A +3x_B \leq 600 \] \[ x_A \geq 0, x_B \geq 0 \]
5. Write a R code to find the solution.
library('lpSolveAPI')
# Set a linear programming with 2 decision variables, no constraints
my.lp <- make.lp(0,2)
# set a minimize problem
lp.control(my.lp,sense='min') ## $anti.degen
## [1] "fixedvars" "stalling"
##
## $basis.crash
## [1] "none"
##
## $bb.depthlimit
## [1] -50
##
## $bb.floorfirst
## [1] "automatic"
##
## $bb.rule
## [1] "pseudononint" "greedy" "dynamic" "rcostfixing"
##
## $break.at.first
## [1] FALSE
##
## $break.at.value
## [1] -1e+30
##
## $epsilon
## epsb epsd epsel epsint epsperturb epspivot
## 1e-10 1e-09 1e-12 1e-07 1e-05 2e-07
##
## $improve
## [1] "dualfeas" "thetagap"
##
## $infinite
## [1] 1e+30
##
## $maxpivot
## [1] 250
##
## $mip.gap
## absolute relative
## 1e-11 1e-11
##
## $negrange
## [1] -1e+06
##
## $obj.in.basis
## [1] TRUE
##
## $pivoting
## [1] "devex" "adaptive"
##
## $presolve
## [1] "none"
##
## $scalelimit
## [1] 5
##
## $scaling
## [1] "geometric" "equilibrate" "integers"
##
## $sense
## [1] "minimize"
##
## $simplextype
## [1] "dual" "primal"
##
## $timeout
## [1] 0
##
## $verbose
## [1] "neutral"
set.objfn(my.lp,c(2,3))
# set the objective function
add.constraint(my.lp,c(1,0),'>=',125)
add.constraint(my.lp,c(1,1),'>=',350)
add.constraint(my.lp,c(2,1),'<=',600)
set.bounds(my.lp,lower=rep(0,2),columns=c(1:2))
solve(my.lp)## [1] 0
## [1] 800
## [1] 250 100
The optimal cost is 800 and with (250, 100).
2. Integer programing
2.1 Example:
Par, Inc., is a small manufacturer of golf equipment and supplies whose management has decided to move into the market for medium- and high-priced golf bags.
Par, Inc.’s distributor has agreed to buy all the golf bags Par, Inc., produces over the next three months.
The number of hours for producing each type of bag is summarized in the below table:
Available working hours for next 3 months:
- 630 hours for cutting and dyeing,
- 708 hours for finishing,
- and 135 hours for inspection and packaging will
Profit contribution of $10 for every standard bag and $9 for every deluxe bag produced.
How to determine the number of standard bags and deluxe bags to produce in order to maximize total profit contribution.
2.1.1 Problem formulation
1. What are decision variables need to be solved?
Denote that S and D are the number of standard bags and deluxe bag, respectively.
2. What is the objective function to optimize?
The total profit contribution is: \[10S + 9D\]
The object is to maximize the total profit contribution.
\[ Maximize \ 10S + 9D \]
3. What are constraints?
Four production time limits limit the quantity of ordinary and deluxe bags that may be manufactured.
Constraint 1 : Number of hours of cutting and dyeing
time used must be less than or equal to 630 hours.
\[ \frac{7}{10}S + 1D \leq 630\]
Constraint 2 : Number of hours of sewing used must
be less than or equal to 600 hours.
\[ \frac{1}{2}S + \frac{5}{6}D \leq 600
\]
Constraint 3 : Number of hours of finishing used must be less than or equal to 708 hours. \[ 1S + \frac{2}{3}D \leq 708 \] Constraint 4 : Number of hours of inspection and packaging used must be less than or equal to 135 hours. \[ \frac{1}{10}S + \frac{1}{4}D \leq 135 \]
4. Write a R code to find the solution.
First of all, we obtain all the constraints, the linear programing can be written as: \[ Maximize \ 10S + 9D \] \[ s.t \ \frac{7}{10}S + 1D \leq 630\] \[ \frac{1}{2}S + \frac{5}{6}D \leq 600 \] \[ 1S + \frac{2}{3}D \leq 708 \] \[ \frac{1}{10}S + \frac{1}{4}D \leq 135 \] \[ S \geq 0, D \geq 0 \]
my.lp <- make.lp(0,2) ### Set a linear programming with 2 decision variables, no constraints
lp.control(my.lp,sense='max') ### set a maximize problem## $anti.degen
## [1] "fixedvars" "stalling"
##
## $basis.crash
## [1] "none"
##
## $bb.depthlimit
## [1] -50
##
## $bb.floorfirst
## [1] "automatic"
##
## $bb.rule
## [1] "pseudononint" "greedy" "dynamic" "rcostfixing"
##
## $break.at.first
## [1] FALSE
##
## $break.at.value
## [1] 1e+30
##
## $epsilon
## epsb epsd epsel epsint epsperturb epspivot
## 1e-10 1e-09 1e-12 1e-07 1e-05 2e-07
##
## $improve
## [1] "dualfeas" "thetagap"
##
## $infinite
## [1] 1e+30
##
## $maxpivot
## [1] 250
##
## $mip.gap
## absolute relative
## 1e-11 1e-11
##
## $negrange
## [1] -1e+06
##
## $obj.in.basis
## [1] TRUE
##
## $pivoting
## [1] "devex" "adaptive"
##
## $presolve
## [1] "none"
##
## $scalelimit
## [1] 5
##
## $scaling
## [1] "geometric" "equilibrate" "integers"
##
## $sense
## [1] "maximize"
##
## $simplextype
## [1] "dual" "primal"
##
## $timeout
## [1] 0
##
## $verbose
## [1] "neutral"
set.objfn(my.lp,c(10,9))
### set the objective function
add.constraint(my.lp,c(7/10,1),'<=',630)
add.constraint(my.lp,c(1/2,5/6),'<=',600)
add.constraint(my.lp,c(1,2/3),'<=',708)
add.constraint(my.lp,c(1/10,1/4),'<=',135)
set.type(my.lp,1:2,'integer')
set.bounds(my.lp,lower=rep(0,2),columns=c(1:2))
solve(my.lp)## [1] 0
## [1] 7668
## [1] 540 252
The optimal cost is 7668 and with (540, 252).
3. Financial Planning
3.1 Case study
Hewlitt Corporation established an early retirement program as part of its corporate restructuring.
At the close of the voluntary sign-up period, 68 employees had elected early retirement.
As a result of these early retirements, the company incurs the following obligations over the next eight years:
| Year | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|
| Cash requirement | 430 | 210 | 222 | 231 | 240 | 195 | 225 | 255 |
The cash requirements (in thousands of dollars) are due at the beginning of each year.
The corporate treasurer must determine how much money F must be set at the beginning of year 1 to meet the eight yearly financial obligations as they come due.
The financing plan for the retirement program includes investments in annually coupon bonds as well as savings.
The investments in coupon bonds with faced value $1000 are limited to three choices:
| Bond | Price | Coupon Rate (%) | Year to Maturity |
|---|---|---|---|
| Type 1 | $1150 | 8.875 | 5 |
| Type 2 | $1000 | 5.500 | 6 |
| Type 3 | $1350 | 11.750 | 7 |
Investments in bonds can take place only in this first year, and the bonds will be held until maturity.
Any funds not invested in bonds will be placed in savings and earn interest at an annual rate of 4%.
The objective function is to minimize the total dollars F needed to meet the retirement plan’s eight-year obligation.
Problem formulation
1.What are decision variables? Let:
\(F\) = total dollars required to meet the retirement plan’s eight-year obligation
\(x_1\) = units of bond 1 purchased at the beginning of year 1
\(x_2\) = units of bond 2 purchased at the beginning of year 1
\(x_3\) = units of bond 3 purchased at the beginning of year 1
\(S_i\) = amount placed in savings at the beginning of year \(i\) for i=1,2,…,8
2.What is the objective fuction?
The objective function is to minimize the total amount needed to meet the retirement plan’s eight-year obligation.\((F)\)
\[Minimize \ F\] 3. What are constraints?
\[objective \ fuction: minimize \ F\] \[ s.t \ Year \ 1: F - 1.15x_1 - x_2 - 1.35x_3 - s_1 = 430\] \[ Year \ 2: 0.08875x_1 + 0.055x_2 + 0.1175x_3 + (1+0.04)s_1 - s_2 = 210\] \[ Year \ 3: 0.08875x_1 + 0.055x_2 + 0.1175x_3 + (1+0.04)s_2 - s_3 = 222\] \[ Year \ 4: 0.08875x_1 + 0.055x_2 + 0.1175x_3 + (1+0.04)s_3 - s_4 = 231\] \[ Year \ 5: 0.08875x_1 + 0.055x_2 + 0.1175x_3 + (1+0.04)s_4 - s_5 = 240\] \[ Year \ 6: 1.08875x_1 + 0.055x_2 + 0.1175x_3 + (1+0.04)s_5 - s_6 = 195\] \[ Year \ 7: 1.055x_2 + 0.1175x_3 + (1+0.04)s_6 - s_7 = 225\] \[ Year \ 8: 1.1175x_3 + (1+0.04)s_7 - s_8 = 255\]
4. Write a R code to find the solution.
my.lp <- make.lp(0,12) ### Set a linear programming with 12 decision variables, no constraints
# Objective function
lp.control(my.lp,sense='min') ### set a maximize problem## $anti.degen
## [1] "fixedvars" "stalling"
##
## $basis.crash
## [1] "none"
##
## $bb.depthlimit
## [1] -50
##
## $bb.floorfirst
## [1] "automatic"
##
## $bb.rule
## [1] "pseudononint" "greedy" "dynamic" "rcostfixing"
##
## $break.at.first
## [1] FALSE
##
## $break.at.value
## [1] -1e+30
##
## $epsilon
## epsb epsd epsel epsint epsperturb epspivot
## 1e-10 1e-09 1e-12 1e-07 1e-05 2e-07
##
## $improve
## [1] "dualfeas" "thetagap"
##
## $infinite
## [1] 1e+30
##
## $maxpivot
## [1] 250
##
## $mip.gap
## absolute relative
## 1e-11 1e-11
##
## $negrange
## [1] -1e+06
##
## $obj.in.basis
## [1] TRUE
##
## $pivoting
## [1] "devex" "adaptive"
##
## $presolve
## [1] "none"
##
## $scalelimit
## [1] 5
##
## $scaling
## [1] "geometric" "equilibrate" "integers"
##
## $sense
## [1] "minimize"
##
## $simplextype
## [1] "dual" "primal"
##
## $timeout
## [1] 0
##
## $verbose
## [1] "neutral"
set.objfn(my.lp,c(1, rep(0, 11)))
# Constraints
# Year 1:
add.constraint(my.lp,c(1,-1.15,-1,- 1.35,-1, rep(0, 7)),'=',430)
# Year 2:
add.constraint(my.lp,c(0,0.08875,0.055,0.1175,1.04,-1, rep(0, 6)),'=',210)
# Year 3: $$0.08875B1 + 0.055B2 + 0.1175B3 + 1.04S2 - S3 = 222 $$
add.constraint(my.lp,c(0,0.08875,0.055,0.1175,0,1.04,-1, rep(0, 5)),'=',222)
# Year 4: $$0.08875B1 + 0.055B2 + 0.1175B3 +1.04S3 - S4 = 231 $$
add.constraint(my.lp,c(0,0.08875,0.055,0.1175,0,0,1.04,-1, rep(0, 4)),'=',231)
# Year 5: $$0.08875B1 + 0.055B2 + 0.1175B3 + 1.04S4 - S5 = 240$$
add.constraint(my.lp,c(0,0.08875,0.055,0.1175,0,0,0,1.04,-1, rep(0, 3)),'=',240)
# Year 6: $$1.08875B1 + 0.055B2 + 0.1175B3 + 1.04S5 - S6 = 195 $$
add.constraint(my.lp,c(0,1.08875,0.055,0.1175,0,0,0,0,1.04,-1, rep(0, 2)),'=',195)
# Year 7: $$1.055B2 + 0.1175B3 + 1.04S6 - S7 = 225 $$
add.constraint(my.lp,c(0,0,1.055,0.1175,0,0,0,0,0,1.04,-1, 0),'=',225)
# Year 8: $$1.1175B3+ 1.04S7 - S8 = 255 $$
add.constraint(my.lp,c(0,0,0,1.1175,0,0,0,0,0,0,1.04,-1),'=',255)
## positive variables
set.bounds(my.lp,lower=rep(0,12),columns=c(1:12))
## natural numbers
set.type(my.lp,2:4,'integer')
solve(my.lp)## [1] 0
## [1] 1728.803
## [1] 1728.803 145.000 188.000 228.000 636.253 501.702 349.769 182.759
## [9] 0.068 0.069 0.202 0.000
Practice
- Acompany incurs the following obligations over the next 7 years
| Year | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
| Cash requirement | 150 | 1000 | 1200 | 1800 | 1100 | 1800 | 2200 |
The cash requirements (in thousands of dollars) are due at the beginning of each year.
The company treasurer must determine how much money F must be set at the beginning of year 1 to meet the 7-yearly financial obligations as they come due.
The financing plan for the retirement program includes investments in annually coupon bonds as well as savings.
The investments in coupon bonds with faced value $100 are limited to 10 choices
| Bond | Price | Coupon Rate (%) | Years to Maturity |
|---|---|---|---|
| Type 1 | $95.2 | 0 | 1 |
| Type 2 | $102 | 9 | 2 |
| Type 3 | $104 | 8 | 3 |
| Type 4 | $110 | 10 | 3 |
| Type 5 | $92.9 | 5 | 4 |
| Type 6 | $97.2 | 7 | 5 |
| Type 7 | $93.1 | 6 | 5 |
| Type 8 | $99.5 | 8 | 6 |
| Type 9 | $94.8 | 7 | 6 |
| Type 10 | $109 | 10 | 6 |
Investments in bonds can take place only in this first year, and the bonds will be held until maturity.
Any funds not invested in bonds will be placed in savings and earn interest at an annual rate of 5%.
The objective function is to minimize the total dollars \(F\) needed to meet the retirement plan’s eight-year obligation.
Problem formulation
1. What are decision variables?
Let:
\(F\) = total dollars required to meet the retirement plan’s eight-year obligation
\(x_1\) = units of bond 1 purchased at the beginning of year 1
\(x_2\) = units of bond 2 purchased at the beginning of year 1
\(x_3\) = units of bond 3 purchased at the beginning of year 1
\(S_i\) = amount placed in savings at the beginning of year \(i\) for i=1,2,…,8
2. What is the objective function?
The objective function is to minimize the total amount needed to meet the retirement plan’s eight-year obligation.\((F)\)
3. What are constraints?
\[objective \ fuction: minimize \ F\] \[ s.t \ Year \ 1: F - 95.2x_1 - 102x_2 - 104x_3 - 110x_4 - 92.9x_5 - 97.2x_6 - 93.1x_7 - 99.5x_8 - 94.8x_9 - 109x_10 - s_1 = 150000\] \[ Year \ 2: 1000x_1 + 9x_2 + 8x_3 + 10x_4 + 5x_5 + 7x_6 + 6x_7 + (1+0.05)s_1 - s_2 = 1000000\] \[ Year \ 3: 1009x_2 + 8x_3 + 10x_4 + 5x_5 + 7x_6 + 6x_7 + (1+0.05)s_2 - s_3 = 1200000\] \[ Year \ 4: 1008x_3 + 1010x_4 + 5x_5 + 7x_6 + 6x_7 + (1+0.05)s_3 - s_4 = 1800000\] \[ Year \ 5: 1005x_5 + 1007x_6 + 1006x_7 + (1+0.05)s_4 - s_5 = 110000\]
4. Write a R code to find the solution.
library(lpSolveAPI)
my.lp <- make.lp(0,13) ### Set a linear programming with 18 decision variables, no constraints
#F,B1,B2,B3,B4,B5,B6,B7,S1,S2,S3,S4,S5
# Objective function
lp.control(my.lp,sense='min') ### set a minimize problem## $anti.degen
## [1] "fixedvars" "stalling"
##
## $basis.crash
## [1] "none"
##
## $bb.depthlimit
## [1] -50
##
## $bb.floorfirst
## [1] "automatic"
##
## $bb.rule
## [1] "pseudononint" "greedy" "dynamic" "rcostfixing"
##
## $break.at.first
## [1] FALSE
##
## $break.at.value
## [1] -1e+30
##
## $epsilon
## epsb epsd epsel epsint epsperturb epspivot
## 1e-10 1e-09 1e-12 1e-07 1e-05 2e-07
##
## $improve
## [1] "dualfeas" "thetagap"
##
## $infinite
## [1] 1e+30
##
## $maxpivot
## [1] 250
##
## $mip.gap
## absolute relative
## 1e-11 1e-11
##
## $negrange
## [1] -1e+06
##
## $obj.in.basis
## [1] TRUE
##
## $pivoting
## [1] "devex" "adaptive"
##
## $presolve
## [1] "none"
##
## $scalelimit
## [1] 5
##
## $scaling
## [1] "geometric" "equilibrate" "integers"
##
## $sense
## [1] "minimize"
##
## $simplextype
## [1] "dual" "primal"
##
## $timeout
## [1] 0
##
## $verbose
## [1] "neutral"
set.objfn(my.lp,c(1, rep(0, 12)))
# Constraints
# Year 1: F-95.2B1-102B2-104B3-110B4-92.9B5-97.2B6-93.1B7-99.5B8-94.8B9-109B10-S1=150000
add.constraint(my.lp,c(1,-952,-1020,-1040,-1100,-929,-972,-931, -1, rep(0, 4)),'=',150000)
# Year 2:
add.constraint(my.lp,c(0,1000,9,8,10,5,7,6,1.05,-1, rep(0, 3)),'=',1000000)
# Year 3:
add.constraint(my.lp,c(rep(0,2),1009,8,10,5,7,6,0,1.05,-1, rep(0, 2)),'=',1200000)
# Year 4:
add.constraint(my.lp,c(rep(0,3),1008,1010,5,7,6,rep(0,2),1.05,-1, rep(0, 1)),'=',1800000)
# Year 5:
add.constraint(my.lp,c(rep(0,5),1005,1007,1006,rep(0,3),1.05,-1),'=',1100000)
## positive variables
lp.control(my.lp, 'positive', 1:12)## $anti.degen
## [1] "none"
##
## $basis.crash
## [1] "none"
##
## $bb.depthlimit
## [1] -50
##
## $bb.floorfirst
## [1] "automatic"
##
## $bb.rule
## [1] "pseudononint" "greedy" "dynamic" "rcostfixing"
##
## $break.at.first
## [1] FALSE
##
## $break.at.value
## [1] -1e+30
##
## $epsilon
## epsb epsd epsel epsint epsperturb epspivot
## 1e-10 1e-09 1e-12 1e-07 1e-05 2e-07
##
## $improve
## [1] "dualfeas" "thetagap"
##
## $infinite
## [1] 1e+30
##
## $maxpivot
## [1] 250
##
## $mip.gap
## absolute relative
## 1e-11 1e-11
##
## $negrange
## [1] -1e+06
##
## $obj.in.basis
## [1] TRUE
##
## $pivoting
## [1] "devex" "adaptive"
##
## $presolve
## [1] "none"
##
## $scalelimit
## [1] 5
##
## $scaling
## [1] "geometric" "equilibrate" "integers"
##
## $sense
## [1] "minimize"
##
## $simplextype
## [1] "dual" "primal"
##
## $timeout
## [1] 0
##
## $verbose
## [1] "neutral"
## [1] 0
## [1] 4648898
## [1] 4648898.000 4724.000 0.000 0.000 0.000 0.000
## [7] 0.000 0.000 1650.000 3725733.000 2712019.000 1047620.081
## [13] 1.085
4. Capital budgeting problem
Intro
- Capital budgeting is the process of identifying and selecting investment projects that bring the most benefit (net present value) under a budget constraint.
Case study
The Ice-Cold Refrigerator Company is considering investing in several projects that have varying capital requirements over the next four years.
The estimated net present value for each project, the capital requirements, and the available capital over the four-year period are shown in below table.
- Four projects are independent to each other.
- Faced with limited capital each year, management would like to select the most profitable projects.
Problem formulation
1. What are decision variables?
\(x_i\) = 1, if project i accepted \(x_i\) = 0, otherwise
2. What is the objective function
\[Maximize \ 90x_1 + 40x_2 + 10x_3 + 37x_4 \]
3. What are constraints? \[Maximize \ 90x_1 + 40x_2 + 10x_3 + 37x_4 \] \[ s.t \ 15x_1 + 10x_2 + 10x_3 + 15x_4 \leq 40\] \[ 20x_1 + 15x_2 + 10x_4 \leq 50\] \[ 20x_1 + 20x_2 + 10x_4 \leq 40\] \[ 15x_1 + 5x_2 + 4x_3 + 10x_4 \leq 35\]
4. Write a R code to find the solution
library(lpSolveAPI)
my.lp <- make.lp(0,4) ### Set a linear programming with 4 decision variables, no constraints
lp.control(my.lp,sense='max') ### set a maximize problem## $anti.degen
## [1] "fixedvars" "stalling"
##
## $basis.crash
## [1] "none"
##
## $bb.depthlimit
## [1] -50
##
## $bb.floorfirst
## [1] "automatic"
##
## $bb.rule
## [1] "pseudononint" "greedy" "dynamic" "rcostfixing"
##
## $break.at.first
## [1] FALSE
##
## $break.at.value
## [1] 1e+30
##
## $epsilon
## epsb epsd epsel epsint epsperturb epspivot
## 1e-10 1e-09 1e-12 1e-07 1e-05 2e-07
##
## $improve
## [1] "dualfeas" "thetagap"
##
## $infinite
## [1] 1e+30
##
## $maxpivot
## [1] 250
##
## $mip.gap
## absolute relative
## 1e-11 1e-11
##
## $negrange
## [1] -1e+06
##
## $obj.in.basis
## [1] TRUE
##
## $pivoting
## [1] "devex" "adaptive"
##
## $presolve
## [1] "none"
##
## $scalelimit
## [1] 5
##
## $scaling
## [1] "geometric" "equilibrate" "integers"
##
## $sense
## [1] "maximize"
##
## $simplextype
## [1] "dual" "primal"
##
## $timeout
## [1] 0
##
## $verbose
## [1] "neutral"
set.objfn(my.lp,c(90,40,10,37))
add.constraint(my.lp,c(15,10,10,15),'<=',40)
add.constraint(my.lp,c(20,15,0,10),'<=',50)
add.constraint(my.lp,c(20,20,0,10),'<=',40)
add.constraint(my.lp,c(15,5,4,10),'<=',35)
set.type(my.lp,1:4,'binary')
solve(my.lp)## [1] 0
## [1] 140
## [1] 1 1 1 0
Exercise
A company has identified a number of promising projects. The cash flows (with unit $1000) for the first two years are shown in the following table.
| Project | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
| Outplay 1 | 90 | 80 | 50 | 20 | 40 | 80 | 80 |
| Outplay 2 | 58 | 80 | 100 | 64 | 50 | 20 | 100 |
| NPV | 150 | 200 | 100 | 100 | 120 | 150 | 240 |
The company managers have decided that they can allocate up to $250,000 in each of the first 2 years to fund these projects. If the money spent for each year is less than the budget allowance, the remaining money can be invested at rate 5% per year and then added to the next year’s budget. The problem is to choose an optimal set of investment projects to maximize the obtained profit (net present value).
1. What are decision variables?
\(x_i\) = 1, if project i accepted \(x_i\) = 0, otherwise
2. What is the objective function?
\[Maximize \ 150x_1 + 200x_2 + 100x_3 + 100x_4 + 120x_5 + 150x_6 + 240x_7 \]
3. What are constraints? \[Maximize \ 150x_1 + 200x_2 + 100x_3 + 100x_4 + 120x_5 + 150x_6 + 240x_7 \] \[s.t \ 90x_1 + 80x_2 + 50x_3 + 20x_4 + 40x_5 + 80x_6 + 80x_7 + s_1 = 250 \] \[ 50x_1 + 80x_2 + 100x_3 + 64x_4 + 50x_5 + 20x_6 + 100x_7 - s_1 \leq 250 \]
4. Write a R code to find the solution
library(lpSolveAPI)
my.lp <- make.lp(0,8) ### Set a linear programming with 4 decision variables, no constraints
lp.control(my.lp,sense='max') ### set a maximize problem## $anti.degen
## [1] "fixedvars" "stalling"
##
## $basis.crash
## [1] "none"
##
## $bb.depthlimit
## [1] -50
##
## $bb.floorfirst
## [1] "automatic"
##
## $bb.rule
## [1] "pseudononint" "greedy" "dynamic" "rcostfixing"
##
## $break.at.first
## [1] FALSE
##
## $break.at.value
## [1] 1e+30
##
## $epsilon
## epsb epsd epsel epsint epsperturb epspivot
## 1e-10 1e-09 1e-12 1e-07 1e-05 2e-07
##
## $improve
## [1] "dualfeas" "thetagap"
##
## $infinite
## [1] 1e+30
##
## $maxpivot
## [1] 250
##
## $mip.gap
## absolute relative
## 1e-11 1e-11
##
## $negrange
## [1] -1e+06
##
## $obj.in.basis
## [1] TRUE
##
## $pivoting
## [1] "devex" "adaptive"
##
## $presolve
## [1] "none"
##
## $scalelimit
## [1] 5
##
## $scaling
## [1] "geometric" "equilibrate" "integers"
##
## $sense
## [1] "maximize"
##
## $simplextype
## [1] "dual" "primal"
##
## $timeout
## [1] 0
##
## $verbose
## [1] "neutral"
set.objfn(my.lp,c(150,200,100,100,120,150,240,0))
add.constraint(my.lp,c(90,80,50,20,40,80,80,1),'=',250)
add.constraint(my.lp,c(58,80,100,64,50,20,100,-1.05),'<=',250)
set.type(my.lp,1:7,'binary')
solve(my.lp)## [1] 0
## [1] 610
5. Dependent projects’ selection (optional)
Intro
Sometimes various projects are interdependent, i.e., the feasibility of one being dependent on whether others are undertaken.
There are several independent goals, but each goal has more than possible method of implementation (sub-projects).
Case study: County transportation choices
A transportation authority, with the total budget 5 million dollars, wishes
- to construct a road between Augen and Burger cities: choose 1 of 4 below sub projects A1: Concrete 2 lanes A2: Concrete 4 lanes A3: Asphalt2 lanes A4: Asphalt 4 lanes
| Project | A1 | A2 | A3 | A4 |
|---|---|---|---|---|
| Cost (KUSD) | 2000 | 3000 | 1500 | 2200 |
| NPV (KUSD) | 4000 | 5000 | 3000 | 4300 |
- to improve Cay Road bridge: choose 1 of 3 below sub projects
| Project | Repair existing | Add lane | New structure |
|---|---|---|---|
| Cost (KUSD) | 500 | 1500 | 2500 |
| NPV (KUSD) | 1000 | 1500 | 2500 |
- to build more traffic control in Downsberg: choose 1 of 3 below sub projects
| Project | Repair existing | Add lane | New structure |
|---|---|---|---|
| Cost (KUSD) | 100 | 600 | 1000 |
| NPV (KUSD) | 300 | 1000 | 2000 |
Problem formulation
1. What are decision variables?
\(x_i\) = 1, if project i
accepted
\(x_i\) = 0, otherwise
2. What is the objective function? \[Maximize \ 4000x_1 + 5000x_2 + 3000x_3 + 4300x_4 + 1000x_5 + 1500x_6 + 2500x_7 + 300x_8 + 1000x_9 + 2000x_{10}\]
3. What are constraints?
\[Maximize \ 4000x_1 + 5000x_2 + 3000x_3 + 4300x_4 + 1000x_5 + 1500x_6 + 2500x_7 + 300x_8 + 1000x_9 + 2000x_{10}\]
\[s.t \ 2000x_1 + 3000x_2 + 1500x_3 + 2200x_4 + 500x_5 + 1500x_6 + 2500x_7 + 100x_8 + 600x_9 + 1000x_{10}\]
\[ x_1 + x_2 + x_3 + x_4 = 1\]
\[ x_5 + x_6 + x_7 = 1\]
\[ x_8 + x_9 + x_{10} = 1\] 4. Write a R code to find the solution.
library(lpSolveAPI)
my.lp <- make.lp(0,10) ### Set a linear programming with 9 decision
lp.control(my.lp,sense='max') ### set a maximize problem## $anti.degen
## [1] "fixedvars" "stalling"
##
## $basis.crash
## [1] "none"
##
## $bb.depthlimit
## [1] -50
##
## $bb.floorfirst
## [1] "automatic"
##
## $bb.rule
## [1] "pseudononint" "greedy" "dynamic" "rcostfixing"
##
## $break.at.first
## [1] FALSE
##
## $break.at.value
## [1] 1e+30
##
## $epsilon
## epsb epsd epsel epsint epsperturb epspivot
## 1e-10 1e-09 1e-12 1e-07 1e-05 2e-07
##
## $improve
## [1] "dualfeas" "thetagap"
##
## $infinite
## [1] 1e+30
##
## $maxpivot
## [1] 250
##
## $mip.gap
## absolute relative
## 1e-11 1e-11
##
## $negrange
## [1] -1e+06
##
## $obj.in.basis
## [1] TRUE
##
## $pivoting
## [1] "devex" "adaptive"
##
## $presolve
## [1] "none"
##
## $scalelimit
## [1] 5
##
## $scaling
## [1] "geometric" "equilibrate" "integers"
##
## $sense
## [1] "maximize"
##
## $simplextype
## [1] "dual" "primal"
##
## $timeout
## [1] 0
##
## $verbose
## [1] "neutral"
set.objfn(my.lp,c(4000,5000,3000,4300,1000,1500,2500,300,1000,2000))
add.constraint(my.lp,c(rep(1,4),rep(0,6)),'=',1)
add.constraint(my.lp,c(rep(0,4),rep(1,3),rep(0,3)),'=',1)
add.constraint(my.lp,c(rep(0,4),rep(0,3),rep(1,3)),'=',1)
add.constraint(my.lp,c(2000,3000,1500,2200,500,1500,2500,100,600,1000),'<=',5000)
set.type(my.lp,1:10,'binary')
solve(my.lp)## [1] 0
## [1] 8000
## [1] 0 1 0 0 1 0 0 0 0 1