2016-10-11 1 views
1

Je commence tout juste à apprendre R et je suis tombé sur quelque chose que je ne sais pas comment gérer dans le code.Trouver l'équipe de projet optimale en utilisant R

Je crée un data.frame avec un groupe d'individus disponibles pour être affectés à un projet. Le projet nécessite un BA, un PM, deux SA, et une personne supplémentaire qui peut être SA ou BA. Chaque personne a une cote et un coût associé, j'ai besoin de la note maximale tout en gardant le coût en dessous d'un certain seuil. Je ne suis pas sûr comment accomplir la partie en gras du scénario ci-dessus .. Le code ci-dessous fonctionne mais ne tient pas compte de la BA/SA supplémentaire.

(Ceci est auto-étude .. non devoirs assignés)

de sortie EDIT-désiré où la dernière ligne peut être soit de la SA ou la position de 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 

code:

#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), ]) 
+0

Ce n'est pas vraiment clair ce que vous voulez avoir comme sortie. Pouvez-vous s'il vous plaît montrer quel est le but final souhaité? – gented

+0

a ajouté la sortie désirée .. espoir qui éclaircit mes intentions. – M3SSYM4RV1N

+1

Voir la réponse de Ram à http://stackoverflow.com/questions/19250787/either-or-constraints-in-lpsolveapi –

Répondre

1

si je suis la bonne question, cela pourrait fonctionner:

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), ]) 

ce que je fais est de modifier certaines contraintes et l'ajout d'un nouveau: le nombre de BA doit être> = 1. Nombre de SA> = 2, et la somme de BA et SA doit être 4, de sorte que vous un Choisis toujours 5 personnes.

Cela donne cependant une autre solution que ce écrit par l'OP:

 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 

Cependant, la somme la cote de cette solution donne 438, tandis que le résultat op est de 437, ce qui devrait être correct.

HTH.

+0

mmm, je vois maintenant que vous pourriez probablement éviter quelques contraintes: vous avez seulement besoin de quatre: PM = 1, BA> = 1, SA> = 2 et BA + SA == 4. Je reformualte la réponse plus tard. – lbusett

+0

Merci, cela a du sens! Je vais également travailler sur l'optimisation des contraintes hors ligne pour la pratique. – M3SSYM4RV1N

+0

Heureux d'aider - voici la version améliorée et plus simple. – lbusett