Поиск оптимальной команды проекта с использованием R

Я только начинаю изучать R и столкнулся с чем-то, что я не уверен, как обрабатывать в коде.

Я создаю data.frame с пулом людей, которые могут быть назначены для проекта. Проекту нужен один BA, один PM, два SA и один дополнительный человек, который может быть либо SA, либо BA. У каждого человека есть рейтинг и стоимость, связанная с ним, мне нужен максимальный рейтинг, сохраняя стоимость ниже определенного порога.

Я не уверен, как добиться жирной части вышеприведенного сценария. Приведенный ниже код работает, но не учитывает дополнительный BA / SA.

(Это самостоятельная работа.. не назначается домашнее задание)

РЕДАКТИРОВАНИЕ Желаемый выход, где последний ряд может быть либо в позиции SA, либо в позиции BA.

name     position rating cost   BA PM SA  
Matt        SA     95    9500   0  0  1    
Aaron       BA     85    4700   1  0  0    
Stephanie   SA     95    9200   0  0  1    
Molly       PM     88    5500   0  1  0    
Jake        SA     74    5300   0  0  1

Код:

#load libraries
library(lpSolve)

# create data.frame
name = c("Steve", "Jeremy", "Matt", "Aaron", "Stephanie", "Molly", "Jake", "Tony", "Jay", "Katy", "Alison") 
position = c("BA", "PM", "SA", "BA", "SA", "PM", "SA", "SA", "PM", "BA", "SA")
rating = c(75, 90, 95, 85, 95, 88, 74, 81, 55, 65, 68) 
cost = c(5000, 8000, 9500, 4700, 9200, 5500, 5300, 7300, 3300, 4100, 4400)
df = data.frame(name, position, rating, cost)

# create restrictions
num_ba = 1
num_pm = 1
num_sa = 2
max_cost = 35000

# create vectors to constrain by position
df$BA = ifelse(df$position == "BA", 1, 0)
df$PM = ifelse(df$position == "PM", 1, 0)
df$SA = ifelse(df$position == "SA", 1, 0)

# vector to optimize against
objective = df$rating

# constraint directions
const_dir <- c("=", "=", "=", "<=")

# matrix
const_mat = matrix(c(df$BA, df$PM, df$SA, df$cost), 4, byrow=TRUE)
const_rhs = c(num_ba, num_pm, num_sa, max_cost)

#solve
x = lp("max", objective, const_mat, const_dir, const_rhs, all.bin=TRUE, all.int=TRUE)
print(df[which(x$solution==1), ])

1 ответ

Решение

Если я правильно понял вопрос, это может сработать:

 library(lpSolve)

 # create data.frame
 name = c("Steve", "Jeremy", "Matt", "Aaron", "Stephanie", "Molly", "Jake", "Tony", "Jay", "Katy", "Alison") 
position = c("BA", "PM", "SA", "BA", "SA", "PM", "SA", "SA", "PM", "BA", "SA")
rating = c(75, 90, 95, 85, 95, 88, 74, 81, 55, 65, 68) 
cost = c(5000, 8000, 9500, 4700, 9200, 5500, 5300, 7300, 3300, 4100, 4400)

df = data.frame(name, position, rating, cost)

# create restrictions
num_pm = 1
min_num_ba = 1
min_num_sa = 2
tot_saba   = 4
max_cost = 35000

# create vectors to constrain by position
df$PM = ifelse(df$position == "PM", 1, 0)
df$minBA = ifelse(df$position == "BA", 1, 0)
df$minSA = ifelse(df$position == "SA", 1, 0)
df$SABA = ifelse(df$position %in% c("SA","BA"), 1, 0)

# vector to optimize against
objective = df$rating

# constraint directions
const_dir <- c("==", ">=", "<=", "==", "<=")

# matrix
const_mat = matrix(c(df$PM, df$minBA, df$minSA, df$SABA, df$cost), 5, byrow=TRUE)
const_rhs = c(num_pm, min_num_ba,min_num_sa, tot_saba, max_cost)

#solve
x = lp("max", objective, const_mat, const_dir, const_rhs, all.bin=TRUE, all.int=TRUE)
print(df[which(x$solution==1), ])

я изменяю некоторые ограничения и добавляю новое: количество BA должно быть>= 1. Число SA >= 2, а сумма BA и SA должна быть 4, так что вы всегда выбираете 5 человек.

Это, однако, дает другое решение, чем написанное ФП:

       name position rating cost PM minBA minSA SABA
1     Steve       BA     75 5000  0     1     0    1
3      Matt       SA     95 9500  0     0     1    1
4     Aaron       BA     85 4700  0     1     0    1
5 Stephanie       SA     95 9200  0     0     1    1
6     Molly       PM     88 5500  1     0     0    0

Однако суммирование рейтинга этого решения дает 438, а результат операции - 437, так что это должно быть правильно.

НТН.

Другие вопросы по тегам