2016-08-17 53 views
1

遇到麻煩試圖建立上的previous question[R隊員名單約束與lpsolve - 必須選擇從Team

的基礎上至少爲x的球員,我想優化,以便有至少3名球員同一支球隊,但我不在乎它是哪支球隊。

在下面的代碼中,我可以蠻力從熊隊(或我指定的其他球隊)中挑選3名球員。你會如何選擇來自同一隊,任何球隊的三名球員的最佳陣容?

library(Rglpk) 
DF <- data.frame(Team=c(rep("Bears",5), rep("Jets",5), rep("49ers", 5)), Player=c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"), Role=c(rep(c("WR", "RB", "TE"),5)), Avgpts=c(22, 19, 30, 25, 20, 21, 26, 14, 21, 13, 11, 8, 4, 3, 5), Salary=c(930, 900, 1300, 970, 910, 920, 980, 720, 650, 589, 111, 1239, 145, 560, 780)) 
obj = DF$Avgpts 
con = rbind(as.numeric(DF$Role=="WR"), as.numeric(DF$Role=="RB"), as.numeric(DF$Role=="TE"), as.numeric(DF$Team == "Bears"), DF$Salary) 
dir = c("==","==","==","==","<=") 
rhs = c(1,1,1,3,100000) 
sol <- Rglpk_solve_LP(obj = obj 
       , mat = con 
       , dir = dir 
       , rhs = rhs 
       , types = rep("B", length(DF$Team)) 
       , max=TRUE) 

solution <- DF[sol$solution==1,] 
+0

通常,鏈接可以,但是您的代碼應該自己運行。這意味着創建'DF'並調用'library(lpSolve)'和其他任何東西。 – Frank

+1

對不起,我改了這個例子,讓它運行。它目前的條件是硬編碼從熊隊中選出3名球員,但我想從同一時間挑選最好的3名球員,無論哪支球隊碰巧都是。 – spantz

回答

0

請原諒我,如果我得到一些術語錯誤,但這裏是我結束瞭解決方案。每個球員被視爲一個專欄,我也爲每個球隊設立一個專欄。我爲每個Team = Team輸入了一個虛擬變量,這個數值等於我希望在單個球隊中獲得的最少球員人數。

library("lpSolveAPI") 
DF <- data.frame(Team=c(rep("Bears",5), rep("Jets",5), rep("49ers", 5)), Player=c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"), Role=c(rep(c("WR", "RB", "TE"),5)), Avgpts=c(22, 19, 30, 25, 20, 21, 26, 14, 21, 13, 11, 8, 4, 3, 5), Salary=c(930, 900, 1300, 970, 910, 920, 980, 720, 650, 589, 111, 1239, 145, 560, 780)) 

ncol <- nrow(DF) # of players in DF 
nteams <- length(unique(DF$Team)) 
teams <- unique(DF$Team) 

lp_rowpicker <- make.lp(ncol=(ncol+nteams)) 

obj_vals <- DF[, "Avgpts"] 
set.objfn(lp_rowpicker, c(obj_vals, rep(0, nteams))) #dummy 0s for team variable 
lp.control(lp_rowpicker,sense='max') 
set.type(lp_rowpicker, columns=1:(ncol+nteams), type = "binary") 
add.constraint(lp_rowpicker, xt=c(DF$Salary, rep(0, nteams)), type="<=", rhs=35000) 
add.constraint(lp_rowpicker, xt=c(as.numeric(DF$Role=="WR"), rep(0, nteams)), type="=", rhs=1) 
add.constraint(lp_rowpicker, xt=c(as.numeric(DF$Role=="RB"), rep(0, nteams)), type="=", rhs=1) 
add.constraint(lp_rowpicker, xt=c(as.numeric(DF$Role=="TE"), rep(0, nteams)), type="=", rhs=1) 

我然後設置一個約束設置爲一個團隊的列數等於總數的球隊減去隊伍的數量我要在最佳的解決方案。在這種情況下,因爲我正在尋找數據框中3個球隊中的1個球隊,所以2個球隊將被設置爲1,並且設置爲0的球隊將需要至少3名球員才能滿足該排中的最小限制水平。

#3 players total 
add.constraint(lp_rowpicker, xt=c(rep(1, ncol), rep(0, nteams)), type="=", rhs=3) 

# add a constraint that every team must have between 3 and 6 players. 
# put a dummy value of 3 in for each team 
# if the flag for the team column is 0 then 3 players must be selected (each with a value of 1 in that team's column. 
for (i in 1:nteams){ 
    team <- teams[i] 
    add.constraint(lp_rowpicker, lhs=3, xt=c(as.numeric(DF$Team==team), rep(0, i-1), 3, rep(0, nteams-i)), type="<=", rhs=7) 
} 

# one team will not have the dummy value in the team column, forcing at  least 3 players picked from the same team to meet the lhs of the above constraint 
add.constraint(lp_rowpicker, xt=c(rep(0, ncol), rep(1, nteams)), type="=", rhs=(nteams-1)) 

solve(lp_rowpicker) 
get.objective(lp_rowpicker) 
soln <- get.variables(lp_rowpicker)>0 
solution <- DF[soln[0:ncol],] 
print(solution[order(solution$Team),])