-1

I have a function in R fun that returns the cost of decision vector x. The input to the function is an integer vector of length 40. Given input vectors a, b, and c (also of length 40), the function is defined as:

fun <- function(x) sum(pmax(a, b, c*x))

The sum of the input vector needs to be 80. I want to find out an input vector Vec where fun(Vec) is minimized. I am assuming this is a fairly straightforward problem but I am lost on where to begin given I am new to optimization problems in R.

josliber
  • 43,891
  • 12
  • 98
  • 133
  • Thanks @ErwinKalvelagen , I am assuming even after i precalculate I still need to test various permutations of the input vector which sum to 80, i don't really understand how sorting would solve it, can you please explain it to me – Nikhil Kondabala Feb 01 '17 at 12:25

1 Answers1

0

This is a problem with 40 integer-valued decision variables, x_1, x_2, ..., x_40. A way to optimally determine how to set them such that your objective is minimized and they sum to 80 is:

  1. Set all variables to 0
  2. Repeatedly increase by 1 the variable that causes the smallest increase in the objective
  3. Stop once they sum to 80.

(I see that Erwin posted a few hours ago a solution with the same idea)

This can be easily implemented in R. First, let's setup sample input vectors:

set.seed(144)
n <- 40
wanted.sum <- 80
A <- rnorm(n, 10, 1)
B <- rnorm(n, 10, 1)
C <- rnorm(n, 10, 1)

Next, let's compute the incremental cost of adding items number 1 through 80 for each of our 40 variables:

inc.cost <- expand.grid(var=factor(1:n), num=1:80)
inc.cost$cost <- with(inc.cost, pmax(A[var], B[var], C[var]*num) -
                                pmax(A[var], B[var], C[var]*(num-1)))
table(head(inc.cost$var[order(inc.cost$cost)], wanted.sum))
#  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 
#  1  1  1  1  1  2  1  2  1  2  1  1  2  1  2 29  1  1  1  2  1  1  1  1  2  1  1  1  2  1  1  2  1  1  2  2  2 
# 38 39 40 
#  1  1  1 
josliber
  • 43,891
  • 12
  • 98
  • 133