Clear environment and load libraries

# Clear environment of variables and functions
rm(list = ls(all = TRUE)) 

# Clear environmet of packages
if(is.null(sessionInfo()$otherPkgs) == FALSE)lapply(paste("package:", names(sessionInfo()$otherPkgs), sep=""), detach, character.only = TRUE, unload = TRUE)
# Load lpSolve package to demonstrate simple LP
library(lpSolve)
library(lpSolveAPI)
library(tidyverse)
## ── Attaching packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.2.1 ──
## ✔ ggplot2 3.2.1     ✔ purrr   0.3.2
## ✔ tibble  2.1.3     ✔ dplyr   0.8.3
## ✔ tidyr   1.0.0     ✔ stringr 1.4.0
## ✔ readr   1.3.1     ✔ forcats 0.4.0
## ── Conflicts ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
`%>%` <- magrittr::`%>%`
library(knitr)
library(kableExtra)
## 
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows

1 Network Map

Code a “network map” showing the different routes workers and supplies may take to reach the African cities from the United States.

2 Plan 1

2.1 Set up problem

2.1.1 Find out the quieckst route

In order to get the quickest route for each city, we need to find out the time cost of each route by different transportation first. According to the fomula: time = distance/speed, we find out the different time cost by each route as followed:

The quickest routes of nine African cities.

Select the minimum value of the time cost of three stratigic cities as following:

The quickest routes of three stratigic cities.

2.1.2 Which routes appear to have significant time bottlenecks that the IFRC should work to reduce?

Use the same fomula but find out the maximum value of time as followed: It takes 195.09 hours from Jacksonville, FL to Luanda, Angola by ship. In addition, Among the nine cities, the route from New York to Luanda,Angola is the significant time bottlenecks that the IFRC should work to reduce. (It takes 186.46 hours)

2.2 Set up the model

Use code to find the quickest route to arrive at the strategic cities.

# Set up model
sp <- make.lp(0, 35)
# Set objective fn and constraints, with 2 dummy nodes as starting point and destination. It ends up having 5 more variables, and 2 more constraints
obj_fn <- c(0,0,20.25,172.11,20.13,17.60,186.46,119.20,19.86,180.83,19.90,17.71,195.09,112.11,10.18,20.64,6.31,5.16,58.32,33.12,1.87,36.84,2.73,3.44,27.78,92.46,5.28,28.30,4.42,3,53.04, 54.50,0,0,0)
set.objfn(sp, obj_fn)
#Add constraint 
#Dummy start point, NY, FL
add.constraint(sp, c( 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "=", 1)
add.constraint(sp, c(-1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "=", 0)
add.constraint(sp, c( 0,-1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "=", 0)

#Transfer cities
add.constraint(sp, c( 0, 0,-1, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0), "=", 0)
add.constraint(sp, c( 0, 0, 0,-1, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), "=", 0)
add.constraint(sp, c( 0, 0, 0, 0,-1, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), "=", 0)
add.constraint(sp, c( 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0), "=", 0)
add.constraint(sp, c( 0, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), "=", 0)
add.constraint(sp, c( 0, 0, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0), "=", 0)

#IFRC cities, dummy destination
add.constraint(sp, c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), "=", 0)
add.constraint(sp, c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 1, 0), "=", 0)
add.constraint(sp, c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1,-1,-1,-1,-1, 0, 0, 1), "=", 0)
add.constraint(sp, c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1,-1), "=",-1)


# Add names, rows are nodes and capacity constraints, columns are edges
dimnames(sp) <- list(c("Start","NY", "FL","Lusaka", "Liberville", "Nairobi", "Khartoum", "Luanda","Dakar","Niamey","Kosongo","Ndjamena","End"), 
                      c("SNY","SFL","NYLu", "NYLi", "NYNa", "NYKh", "NYLua", "NYDa", "FLLu", "FLLi", "FLNa", "FLKh", "FLLua", "FLda", 
                        "LuNia","LiNia","NaNia","KhNia","LuaNia","DaNia","LuKo","LiKo","NaKo","KhKo","LuaKo","DaKo","LuNd","LiNd","NaNd","KhNd","LuaNd",
                        "DaNd","NiaE","KoE","NdE"))
# Write to view the algebraic formulation
write.lp(sp, "MP_prob2.lp",type = 'lp')

# Solve the model
solve(sp)
## [1] 0
# Make results and sensitivity table 
ps <- get.primal.solution(sp)
obj_sa <- get.sensitivity.obj(sp)
rhs_sa <- get.sensitivity.rhs(sp)

nv <- length(get.variables(sp))
mc <- length(get.constr.type(sp))
ov <- paste0("Objective Value = ", ps[1])

sa_tab <- rbind(ps[2:(nv + mc + 1)], 
                round(c(rhs_sa$duals[1:mc], obj_fn), 2),
                round(c(rhs_sa$dualsfrom[1:mc],obj_sa$objfrom), 2),
                round(c(rhs_sa$dualstill[1:mc],obj_sa$objtill), 2)) 
colnames(sa_tab) <- c(rownames(sp), colnames(sp))
rownames(sa_tab) <- c("solution", "duals/coef", "Sens From", "Sens Till")      


sa_tab <- ifelse(sa_tab == -1.000e+30, "-inf", sa_tab)
sa_tab <- ifelse(sa_tab == 1.000e+30, "inf", sa_tab)
# Print the table
knitr::kable(sa_tab, format.args = list(big.mark = ",")) %>%
  kableExtra::kable_styling(bootstrap_options = c("striped", "bordered")) %>% 
  kableExtra::add_footnote(label = ov, notation = "none")
Start NY FL Lusaka Liberville Nairobi Khartoum Luanda Dakar Niamey Kosongo Ndjamena End SNY SFL NYLu NYLi NYNa NYKh NYLua NYDa FLLu FLLi FLNa FLKh FLLua FLda LuNia LiNia NaNia KhNia LuaNia DaNia LuKo LiKo NaKo KhKo LuaKo DaKo LuNd LiNd NaNd KhNd LuaNd DaNd NiaE KoE NdE
solution 1 0 0 0 0 0 0 0 0 0 0 0 -1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
duals/coef 19.9 19.9 19.9 0.04 0 0 2.3 0 0 -0.7 -0.7 -0.7 -0.7 0 0 20.25 172.11 20.13 17.6 186.46 119.2 19.86 180.83 19.9 17.71 195.09 112.11 10.18 20.64 6.31 5.16 58.32 33.12 1.87 36.84 2.73 3.44 27.78 92.46 5.28 28.3 4.42 3 53.04 54.5 0 0 0
Sens From 1 0 0 0 -inf -inf 0 -inf -inf 0 0 0 -1 -0.23 -0.11 19.86 19.9 19.9 -inf 19.9 19.9 18.73 19.9 17.87 17.6 19.9 19.9 0.74 0.7 0.7 3 0.7 0.7 0.74 0.7 0.7 3 0.7 0.7 0.74 0.7 0.7 -inf 0.7 0.7 -2.16 -0.44 -inf
Sens Till 1 0 0 0 inf inf 0 inf inf 0 0 0 -1 0.11 inf inf inf inf 17.71 inf inf inf inf inf inf inf inf inf inf inf inf inf inf inf inf inf inf inf inf inf inf inf 3.44 inf inf inf inf 0.44
Objective Value = 20.6

2.3 Result

  • Fastest route to from departure city to the stategic city: NY - Khartoum - Ndjamena

  • Fastest route takes 20.6 hrs

3 Plan 2

3.1 Set up problem

How should the IFRC satisfy each African city’s need requirements at minimum cost? Where are the significant bottlenecks in the system that the IFRC should work to reduce? Network Map highlighting the least cost route between the U.S. and African cities.

Find out the cheapest way to deliver the workers and cargo.

3.2 Set up the model

# Set up model
prob3 <- make.lp(0, 30)

# Set objective fn 
obj_fn <- c(50,30,55,45,30,32,57,48,61,49,44,56,24,1000,28,22,1000,1000,22,4,25,19,5,5,23,7,2,4,8,9)
set.objfn(prob3, obj_fn)

#Set up requirement node constraints
add.constraint(prob3, c( 150, 240, 150, 150, 240, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "<=", 500000)
add.constraint(prob3, c( 0, 0, 0, 0, 0, 0, 150, 240, 150, 150, 240, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "<=", 500000)

add.constraint(prob3, c(-150, 0, 0, 0, 0, 0,-150, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0), "<=", -150000)
add.constraint(prob3, c( 0,-240, 0, 0, 0, 0, 0,-240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17.7, 0, 0, 0, 0, 0, 17.7, 0, 0, 0, 0), "<=", -100000)
add.constraint(prob3, c( 0, 0,-150, 0, 0, 0, 0, 0,-150, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 150, 0, 0, 0), "<=", -120000)
add.constraint(prob3, c( 0, 0, 0,-150, 0, 0, 0, 0, 0,-150, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 150, 0, 0), "<=", -90000)
add.constraint(prob3, c( 0, 0, 0, 0,-240, 0, 0, 0, 0, 0,-240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17.7, 0, 0, 0, 0, 0, 17.7, 0), "<=", -130000)
add.constraint(prob3, c( 0, 0, 0, 0, 0,-240, 0, 0, 0, 0, 0,-240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17.7, 0, 0, 0, 0, 0, 17.7), "<=", -50000)

add.constraint(prob3, c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -150, 0, -150, -150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "<=", -100000)
add.constraint(prob3, c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-150, -17.7, -150, -150, -17.7, -17.7, 0, 0, 0, 0, 0, 0), "<=", -180000)
add.constraint(prob3, c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-150, -17.7, -150, -150, -17.7, -17.7), "<=", -80000)


# Set up capacity constraints
add.constraint(prob3, c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1), "<=", 840)
add.constraint(prob3, c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0), "<=", 200)
add.constraint(prob3, c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), "<=", 200)


# Add names, rows are nodes and capacity constraints, columns are edges
dimnames(prob3) <- list(c("NY", "FL","Lusaka", "Liberville", "Nairobi", "Khartoum", "Luanda","Dakar","Niamey","Kosongo","Ndjamena", 
                       "Utruck", "UA1", "UA2"), 
                      c("NYLu", "NYLi", "NYNa", "NYKh", "NYLua", "NYDa", "FLLu", "FLLi", "FLNa", "FLKh", "FLLua", "FLda", 
                        "LuNia","LiNia","NaNia","KhNia","LuaNia","DaNia","LuKo","LiKo","NaKo","KhKo","LuaKo","DaKo","LuNd","LiNd","NaNd","KhNd","LuaNd                        ","DaNd"))

# Write to view the algebraic formulation
write.lp(prob3, "MP_prob3.lp",type = 'lp')

3.3 Solve model

# Solve the model
solve(prob3)
## [1] 0
# Make solution/sensitivity analysis table
# Get primal solution
ps <- get.primal.solution(prob3)

# Have to re-enter obj fn to get Sens Ana table since cannot pull from model
obj_fn <- c(50,30,55,45,30,32,57,48,61,49,44,56,24,1000,28,22,1000,1000,22,4,25,19,5,5,23,7,2,4,8,9)

# Get sensitivity analysis
obj_sa <- get.sensitivity.obj(prob3)
rhs_sa <- get.sensitivity.rhs(prob3)

n <- length(get.variables(prob3))
m <- length(get.constr.type(prob3))
ov <- paste0("Objective Value = ", ps[1]*1000)

sa_tab <- rbind(ps[2:(n + m + 1)], 
                c(round(rhs_sa$duals[1:m], 2), obj_fn),
                round(c(rhs_sa$dualsfrom[1:m],obj_sa$objfrom), 2),
                round(c(rhs_sa$dualstill[1:m],obj_sa$objtill), 2)) 
colnames(sa_tab) <- c(rownames(prob3), colnames(prob3))
rownames(sa_tab) <- c("solution", "duals/coef", "Sens From", "Sens Till")      

sa_tab <- ifelse(sa_tab == -1.000e+30, "-inf", sa_tab)
sa_tab <- ifelse(sa_tab == 1.000e+30, "inf", sa_tab)
# Print the table
kable(sa_tab, format.args = list(big.mark = ",")) %>%
  kable_styling(bootstrap_options = c("striped", "bordered")) %>% 
  add_footnote(label = ov, notation = "none")
NY FL Lusaka Liberville Nairobi Khartoum Luanda Dakar Niamey Kosongo Ndjamena Utruck UA1 UA2 NYLu NYLi NYNa NYKh NYLua NYDa FLLu FLLi FLNa FLKh FLLua FLda LuNia LiNia NaNia KhNia LuaNia DaNia LuKo LiKo NaKo KhKo LuaKo DaKo LuNd LiNd NaNd KhNd LuaNd DaNd
solution 5e+05 5e+05 -150000 -99999.9999999999 -120000 -90000.0000000001 -130000 -50000.0000000001 -1e+05 -180000 -80000 0 0 200 266.666666666667 1166.66666666667 0 0 541.666666666667 208.333333333334 733.333333333333 0 1133.33333333333 1466.66666666667 0 0 0 0 0 666.666666666667 0 0 0 10169.4915254237 0 0 0 0 0 0 333.333333333333 200 0 0
duals/coef -0.05 0 -0.38 -0.17 -0.41 -0.33 -0.17 -0.18 -0.47 -0.4 -0.42 0 0 -10 50 30 55 45 30 32 57 48 61 49 44 56 24 1000 28 22 1000 1000 22 4 25 19 5 5 23 7 2 4 8 9
Sens From 5e+05 -inf -150000 -1e+05 -120000 -90000 -130000 -50000 -1e+05 -180000 -80000 -inf -inf 0 48.25 -5.32 54 42 16.44 16.44 56 41.2 51 40.65 41.2 43.2 14 1000 10 -49 1000 1000 2.65 -3.04 -1.35 10.65 4 3.85 6 4.4 -8 -inf 4.4 4.25
Sens Till 610000 inf -40000 10000 50000 130000 -20000 0 0 -70000 -30000 inf inf 533.33 51 36.8 inf inf 32.8 44.8 58.75 inf 62 52 inf inf inf inf inf 32 inf inf inf 4.99 inf inf inf inf inf inf 19 14 inf inf
Objective Value = 310861299.435028

3.4 Result

  • Minimun cost: $310,861,299.43.

  • NewYork needs 267 flights to Lusaka, Zambia, 1167 ships to Libreville, Gabon, 542 ships to Luanda, Angola, and 209 ships to Dakar, Senegal.

  • Florida needs 734 flights to Lusaka, Zambia, 1134 flights to Nairobi, Kenya, and 1147 flights to Khartoum, Sudan.

  • Khartoum, Sudan needs 667 flights Niamey, Niger, and 200 flights to Ndjamena, Chad.

  • Libreville, Gabon needs 10170 trucks to Kosongo, D.R. Congo.

  • Nairobi, Kenya needs 200 flights to Ndjamena, Chad.

  • With an additional flight increase in the route from Khartoum, Sudan to Ndjamena, Chad can decrease $10000 in cost. This would be the bottelneck in the system that IFRC can try to reduce the cost.

4 Plan 3

4.1 Set up problem

How can the IFRC maximize the total amount of cargo that reaches Africa? Where are the significant bottlenecks in the system that the IFRC should work to reduce? Provide a table and/or network map highlighting the maximum cargo and routes between the U.S. and African cities.

Maximize the total amount of cargo that reaches Africa

4.2 Set up the model

# Set up model
prob4 <- make.lp(0, 30)
#set objective function to min
lp.control(prob4,sense="max")
## $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 objective finction
obj_fn <- c(1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
set.objfn(prob4, obj_fn)
#Add aid requirement constraints for each of cities
add.constraint(prob4, c(1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),"<=", 500000) 
add.constraint(prob4, c(0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),"<=", 500000)  

add.constraint(prob4, c(1,0,0,0,0,0,1,0,0,0,0,0,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 50000) 
add.constraint(prob4, c(0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 100000)
add.constraint(prob4, c(0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,0,0,0,0,0), "<=", 130000)
add.constraint(prob4, c(0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,0,0),"<=", 150000) 
add.constraint(prob4, c(0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0), "<=", 90000) 
add.constraint(prob4, c(0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1), "<=", 120000) 

add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0), "<=", 100000)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0), "<=", 180000) 
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1), "<=", 80000) 
#Add Airline Constraints
add.constraint(prob4, c(0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 300*150)
add.constraint(prob4, c(0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 500*150)
add.constraint(prob4, c(0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 500*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 500*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 700*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 600*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), "<=", 200*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0), "<=", 0*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0), "<=", 300*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0), "<=", 140*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0), "<=", 40*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0), "<=", 80*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0), "<=", 0*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1), "<=", 300*150)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0), "<=", 40*150)
#Add Truck Constraints
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 300*17.7)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0), "<=", 250*17.7)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 700*17.7)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 160*17.7)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0), "<=", 240*17.7)
add.constraint(prob4, c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), "<=", 450*17.7)

dimnames(prob3) <- list(c(“NY”, “FL”,“Lusaka”, “Liberville”, “Mairobi”, “Khartoum”, “Luanda”,“Dakar”,“Niamey”,“Kosongo”,“Ndjamena”, “Utruck”, “UA1”, “UA2”), c(“NYLu”, “NYLi”, “NYNa”, “NYKh”, “NYLua”, “NYDa”, “FLLu”, “FLLi”, “FLNa”, “FLKh”, “FLLua”, “FLda”, “LuNia”,“LiNia”,“NaNia”,“KhNia”,“LuaNia”,“DaNia”,“LuKo”,“LiKo”,“NaKo”,“KhKo”,“LuaKo”,“DaKo”,“LuNd”,“LiNd”,“NaNd”,“KhNd”,“LuaNd”,“DaNd”))

# Add names, rows are nodes and capacity constraints, columns are edges
dimnames(prob4) <- list(c("NY", "FL","Dakar","Liberville","Lusaka","Luanda", "Khartoum","Nairobi",  "Niamey","Kosongo","Ndjamena",
                          "UA1","UA2","UA3","UA4","UA5","UA6","UA7","UA8","UA9","UA10","UA11","UA12","UA13","UA14","UA15","Utruck1","Utruck2","Utruck3","Utruck4","Utruck5","Utruck6"),
                          
                          c("NYDa", "NYLi", "NYLua", "NYLu", "NYKh", "NYNa", "FLDa", "FLLi", "FLLua", "FLLu", "FLKh", "FLNa",
                          "DaNia","DaKo","DaNd","LiNia","LiKo","LiNd","LuaNia","LuaKo","LuaNd","LuNia","LuKo","LuNd","KhNia","KhKo","KhNd","NaNia","NaKo","NaNd"))

# Write to view the algebraic formulation
write.lp(prob4, "MP_prob4.lp",type = 'lp')
solve(prob4)
## [1] 0
get.objective(prob4)
## [1] 816170
# Make results and sensitivity table 
ps <- get.primal.solution(prob4)
obj_sa <- get.sensitivity.obj(prob4)
rhs_sa <- get.sensitivity.rhs(prob4)

nv <- length(get.variables(prob4))
mc <- length(get.constr.type(prob4))
ov <- paste0("Objective Value = ", ps[1])

sa_tab <- rbind(ps[2:(nv + mc + 1)], 
                round(c(rhs_sa$duals[1:mc], obj_fn), 2),
                round(c(rhs_sa$dualsfrom[1:mc],obj_sa$objfrom), 2),
                round(c(rhs_sa$dualstill[1:mc],obj_sa$objtill), 2)) 
colnames(sa_tab) <- c(rownames(prob4), colnames(prob4))
rownames(sa_tab) <- c("solution", "duals/coef", "Sens From", "Sens Till")      


sa_tab <- ifelse(sa_tab == -1.000e+30, "-inf", sa_tab)
sa_tab <- ifelse(sa_tab == 1.000e+30, "inf", sa_tab)
# Print the table
knitr::kable(sa_tab, format.args = list(big.mark = ",")) %>%
  kableExtra::kable_styling(bootstrap_options = c("striped", "bordered")) %>% 
  kableExtra::add_footnote(label = ov, notation = "none")
NY FL Dakar Liberville Lusaka Luanda Khartoum Nairobi Niamey Kosongo Ndjamena UA1 UA2 UA3 UA4 UA5 UA6 UA7 UA8 UA9 UA10 UA11 UA12 UA13 UA14 UA15 Utruck1 Utruck2 Utruck3 Utruck4 Utruck5 Utruck6 NYDa NYLi NYLua NYLu NYKh NYNa FLDa FLLi FLLua FLLu FLKh FLNa DaNia DaKo DaNd LiNia LiKo LiNd LuaNia LuaKo LuaNd LuNia LuKo LuNd KhNia KhKo KhNd NaNia NaKo NaNd
solution 5e+05 316170 50000 1e+05 130000 120000 90000 120000 1e+05 40125 66045 45000 66000 63000 75000 105000 90000 0 0 45000 0 6000 12000 0 45000 6000 5310 4425 12390 2832 4248 7965 79185 108142 138673 45000 63000 66000 46170 0 0 75000 90000 105000 55000 12390 7965 0 5310 2832 0 4425 4248 0 0 0 45000 12000 6000 0 6000 45000
duals/coef 0 0 1 1 1 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Sens From 420815 -inf 3830 53830 83830 -inf 43830 73830 53830 -inf -inf 0 -inf -inf 0 96000 78000 -inf 0 0 -inf 0 0 -inf 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 -inf -inf 0 1 1 0 -1 -1 -inf -1 -1 -inf -1 -1 -inf -inf -inf 0 -1 -1 -inf -1 -1
Sens Till 546170 inf 233830 179185 209185 inf 102000 129000 283830 inf inf 75000 inf inf 105000 151170 136170 inf 9000 57000 inf 15000 24000 inf 54000 18000 84495 83610 152265 16787 18203 21920 1 1 1 inf 1 1 1 1 1 inf inf inf 0 inf inf 0 inf inf 0 inf inf 1 0 0 inf inf inf inf inf inf
Objective Value = 816170

4.3 Result

  • The IFRC can maximize the total amount of cargo of 816,170 tons that reaches Africa.

  • The amount of cargo will follow below requirement and routes to reach Africa:

  • NY - Dakar, Senegal [79185 tons], NY - Libreville, Gabon [108142 tons], NY - Luanda, Angola [138673 tons], NY - Lusaka, Zambia [45000 tons],

    NY - Khartoum, Sudan [63000 tons], NY - Nairobi, Kenya [66000 tons]

  • FL - Dakar, Senegal [46170 tons], FL - Lusaka, Zambia [75000 tons], FL - Khartoum, Sudan [90000 tons], FL - Nairobi, Kenya [105000 tons]

  • Dakar - Niamey [55000 tons], Dakar - Kosongo [12390 tons], Dakar - Ndjamena [7965 tons], Libreville - Kosongo [5310 tons], Libreville - Ndjamena [2832 tons] , Luanda - Kosongo [4425 tons], Luanda - Ndjamena [4248 tons], Khartoum - Niamey [45000 tons], Khartoum - Kosongo [12000 tons], Khartoum - Ndjamena [6000 tons], Nairobi - Kosongo [6000 tons], Nairobi - Ndjamena [45000 tons]

For the bottleneck of plan 3, Dakar and Khartoum are taking supplies from both NY and FL, and distributing all supplies to three different african strategic cities. IFRC might need to consider the time and arrangement of this two cities.