I am working on an optimization problem in which my choice variable (to build or not) is a binary variable. The photo attached shows the optimal build choices (solved using Solver in Excel).
I am trying to replicate this problem in R. Minimizing the sum of expected value (EV) with the budget constraint ≤ 30 and build choices as the choice variable.
The problem is that EV changes with the given combination of build decisions. The general formula for it is:
EV = probability of fire (p)*Damage(when there is a fire) + (1-p)*Damage (no fire) + Cost (K).
Damage is 0 when there is no fire. High damage when there is a fire and the plot does not have a tower and low damage when the plot has a tower built on it.
So EV = p*Damage(fire state) + Cost
Plot i: Ten plots of land (size or other attributes do not matter). H: High damage. High damage only if there is no build decision. L: Low damage. Low damage if we chose to build a tower in a given plot. p: Probability of fire. K: Cost of building watch tower. Given B profile: B is a binary variable. B=1 signifies we chose to built in the given plot. EV(B=1): Expected value if we chose to build. EV(B=0): Expected value if we do not build. EV: Final expected value. If we build, EV = EV(B=1) else EV = EV(B=0). Budget constraint: If we build, it is equal to the cost of building, else it is 0.
You can express your problem as binary linear one by having two variables for each row. Those pair of varibles are connected in following way:
data
data <- data.frame(
H = c(50, 55, 58, 98, 60, 78, 88, 69, 78, 63),
L = c(20, 11, 5, 12, 15, 22, 32, 15, 8, 17),
p = c(0.1, 0.2, 0.05, 0.07, 0.5, 0.15, 0.09, 0.02, 0.01, 0.15),
K = c(6, 8, 6, 5, 4, 8, 9, 7, 4, 2)
)
data$EV1 <- data$L * data$p + data$K
data$EV0 <- data$H * data$p
solution
library(lpSolve)
n <- nrow(data)
total_budget <- 30
res <- lp(
direction = "min",
objective = c(data$EV1, data$EV0),
const.mat = rbind(c(data$K, rep(0, n)), cbind(diag(n), diag(n))),
const.dir = c("<=", rep("=", n)),
const.rhs = c(total_budget, rep(1, n)),
all.bin = TRUE
)
res$solution[seq_len(n)]
[1] 0 1 0 1 1 1 0 0 0 1
res$objval
[1] 61.37
sum(data$K[res$solution[seq_len(n)] == 1])
[1] 27
where total_budget
is upper limit on your budget.