Say I have a state of current scores held in a vector:
current_score <- c(60, 59, 78, 79, 76)
I want to decide what scores to increase. I can increase them to some value (say 95) if I choose that index. Each has an associated cost if chosen.
decision <- rep(1, times=length(current_score))
cost <- c(2792, 5207, 1814, 642, 1037)
I also want to have the weighted score/cost of the entire vector to meet some minimum goal.
goal <- 70
How can I find the optimal indexes to choose?
Here's the function I've tried using nonlinear optimization with optim but it always returns 0. I'm also not sure how I can implement it with binary constraints (decision vector should be either 1 or 0).
fn <- function(decision, current_score, cost, goal)
{
# if decision = TRUE, score = 95
# this would provide the constraint coefficients if done in lpSolve
current_score[which(decision == TRUE)] <- 95
# calculate weighted score after decision
wt_score <- sum(current_score*cost)/sum(cost)
# if decision doesn't meet goal, assign arbitrary large value to reject this choice
if(wt_score < goal)
{
decision_cost <- .Machine$double.xmax
} else
{
decision_cost <- sum(decision * cost)
}
return(decision_cost)
}
I would normally set this up as a linear program with lpSolve but the constraint coefficients change along with the decision variables. I'm not sure if I can implement the binary decision constraints with optim. With the approach below, it returns .Machine$double.xmax which is obviously incorrect.
upper <- rep(1, times=length(decision))
lower <- rep(0, times=length(decision))
result <- optim(par=decision, fn=fn, upper=upper, lower=lower, method=c("L-BFGS-B"), current_score = current_score, cost = cost, goal=goal)
For example, decision = c(1,0,0,0,0) provides wt_score = 73.39 and decision_cost = 2792 so it's a better solution.
Edit: FWIW, this is feasible using a genetic algorithm within Excel, but I would like to do it in R
Below it's mentioned this can be set up as a linear problem. The issue I have is how to implement the constraints because they change as the decision variables change. E.g.,
# return a vector that is changed based on the decision variables
constraint_vector <- function(score, x)
{
score <- score[x==TRUE] <- 95
}
lp_min <- function(score, cost, crvs, goal)
{
# create a repair vector
f.obj <- cost
# not constant, but a function of decision variable x
f.con <- constraint_vector(score,x)
f.dir <- c(">=")
f.rhs <- goal
solution <- lp("in", f.obj, f.con, f.dir, f.rhs, all.bin=TRUE)
}