Ограничения условной оптимизации - PullRequest
0 голосов
/ 08 октября 2018

Я пытаюсь добавить некоторые ограничения в мой набор хоккейных данных.Я пытаюсь оптимизировать прогнозируемые точки с учетом ограничений

  1. Зарплата <= 50000 </li>
  2. Центров = 2
  3. Оборона = 2
  4. Крылья =2
  5. Вратарь = 1

Я получил эти ограничения для работы с использованием lpSolveAPI

hockey <- structure(list( Last.Name = c("Doe1", "Doe2", "Doe3", "Doe4", 
"Doe5", "Doe6", "Doe7", "Doe8", "Doe9", "Doe10", "Doe11", "Doe12", 
"Doe13", "Doe14", "Doe15", "Doe16", "Doe17", "Doe18", "Doe19", 
"Doe20", "Doe21", "Doe22", "Doe23", "Doe24", "Doe25", "Doe26", 
"Doe27", "Doe28", "Doe29", "Doe30", "Doe31", "Doe32", "Doe33", 
"Doe34", "Doe35", "Doe36", "Doe37", "Doe38", "Doe39", "Doe40", 
"Doe41", "Doe42", "Doe43", "Doe44", "Doe45", "Doe46", "Doe47", 
"Doe48", "Doe49", "Doe50", "Doe51", "Doe52", "Doe53", "Doe54", 
"Doe55", "Doe56", "Doe57", "Doe58", "Doe59", "Doe60", "Doe61", 
"Doe62", "Doe63", "Doe64", "Doe65", "Doe66", "Doe67", "Doe68", 
"Doe69", "Doe70", "Doe71", "Doe72", "Doe73", "Doe74", "Doe75", 
"Doe76", "Doe77", "Doe78", "Doe79", "Doe80", "Doe81", "Doe82", 
"Doe83", "Doe84", "Doe85", "Doe86", "Doe87", "Doe88", "Doe89", 
"Doe90", "Doe91", "Doe92", "Doe93", "Doe94", "Doe95", "Doe96", 
"Doe97", "Doe98", "Doe99", "Doe100", "Doe101", "Doe102", "Doe103", 
"Doe104", "Doe105", "Doe106", "Doe107", "Doe108", "Doe109", "Doe110", 
"Doe111", "Doe112", "Doe113", "Doe114", "Doe115", "Doe116", "Doe117", 
"Doe118", "Doe119", "Doe120", "Doe121", "Doe122", "Doe123", "Doe124", 
"Doe125", "Doe126", "Doe127", "Doe128", "Doe129", "Doe130", "Doe131", 
"Doe132", "Doe133", "Doe134", "Doe135", "Doe136", "Doe137", "Doe138", 
"Doe139", "Doe140", "Doe141", "Doe142", "Doe143", "Doe144", "Doe145", 
"Doe146", "Doe147", "Doe148", "Doe149", "Doe150", "Doe151", "Doe152", 
"Doe153", "Doe154", "Doe155", "Doe156", "Doe157", "Doe158", "Doe159", 
"Doe160", "Doe161", "Doe162", "Doe163", "Doe164", "Doe165", "Doe166", 
"Doe167", "Doe168", "Doe169", "Doe170", "Doe171", "Doe172", "Doe173", 
"Doe174", "Doe175", "Doe176", "Doe177", "Doe178", "Doe179", "Doe180", 
"Doe_goalie_1", "Doe_goalie_2", "Doe_goalie_3", "Doe_goalie_4", 
"Doe_goalie_5", "Doe_goalie_6", "Doe_goalie_7", "Doe_goalie_8", 
"Doe_goalie_9", "Doe_goalie_10"), Salary = c(4300L, 4200L, 4200L, 
4700L, 4700L, 4500L, 4900L, 4400L, 3600L, 3200L, 3000L, 3000L, 
6300L, 7800L, 4400L, 5800L, 5800L, 4000L, 4000L, 6500L, 5100L, 
4200L, 5800L, 5800L, 3100L, 3200L, 3700L, 3100L, 3100L, 3500L, 
4600L, 4900L, 4400L, 7000L, 7600L, 7200L, 5500L, 7500L, 6300L, 
5600L, 5400L, 5600L, 3400L, 4600L, 3100L, 3100L, 3300L, 3400L, 
6500L, 8000L, 6500L, 7000L, 5900L, 5000L, 5400L, 4400L, 7800L, 
3700L, 3400L, 3100L, 4500L, 3900L, 3800L, 3100L, 3200L, 3500L, 
6500L, 5200L, 6700L, 4700L, 4300L, 5700L, 6300L, 7200L, 5600L, 
3300L, 4900L, 4400L, 5000L, 4700L, 3700L, 3100L, 3300L, 3400L, 
4000L, 4700L, 7700L, 7900L, 7200L, 4800L, 7700L, 7500L, 7500L, 
3200L, 4700L, 3500L, 4700L, 3500L, 3900L, 3000L, 3000L, 3100L, 
7200L, 7100L, 5600L, 6900L, 4300L, 7000L, 6500L, 4300L, 7800L, 
5400L, 3400L, 4900L, 3000L, 3600L, 3500L, 3000L, 3400L, 3500L, 
5200L, 5400L, 5400L, 6500L, 6000L, 5400L, 7200L, 6500L, 8000L, 
4900L, 5400L, 5800L, 4000L, 3100L, 4000L, 3200L, 3000L, 3100L, 
6200L, 7200L, 4800L, 4800L, 7400L, 4000L, 4300L, 5400L, 6600L, 
4600L, 3900L, 5700L, 3900L, 3500L, 3500L, 3100L, 3200L, 3000L, 
5700L, 6800L, 6700L, 6600L, 5800L, 7600L, 7000L, 7800L, 7000L, 
5800L, 5800L, 4800L, 3200L, 4200L, 4000L, 3500L, 3300L, 3100L, 
4900L, 6100L, 7300L, 4700L, 8000L, 5100L, 6700L, 6800L, 6900L, 
6900L, 6800L, 6700L, 6000L, 5800L, 4400L, 6500L), Position = c("C", 
"W", "W", "C", "W", "W", "C", "W", "W", "C", "W", "W", "D", "D", 
"D", "D", "D", "D", "C", "W", "W", "C", "W", "W", "C", "W", "W", 
"C", "W", "W", "D", "D", "D", "D", "D", "D", "C", "W", "W", "C", 
"W", "W", "C", "W", "W", "C", "W", "W", "D", "D", "D", "D", "D", 
"D", "C", "W", "W", "C", "W", "W", "C", "W", "W", "C", "W", "W", 
"D", "D", "D", "D", "D", "D", "C", "W", "W", "C", "W", "W", "C", 
"W", "W", "C", "W", "W", "D", "D", "D", "D", "D", "D", "C", "W", 
"W", "C", "W", "W", "C", "W", "W", "C", "W", "W", "D", "D", "D", 
"D", "D", "D", "C", "W", "W", "C", "W", "W", "C", "W", "W", "C", 
"W", "W", "D", "D", "D", "D", "D", "D", "C", "W", "W", "C", "W", 
"W", "C", "W", "W", "C", "W", "W", "D", "D", "D", "D", "D", "D", 
"C", "W", "W", "C", "W", "W", "C", "W", "W", "C", "W", "W", "D", 
"D", "D", "D", "D", "D", "C", "W", "W", "C", "W", "W", "C", "W", 
"W", "C", "W", "W", "D", "D", "D", "D", "D", "D", "G", "G", "G", 
"G", "G", "G", "G", "G", "G", "G"), Team = c("A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", 
"C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "D", "D", 
"D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", 
"D", "D", "D", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", 
"E", "E", "E", "E", "E", "E", "E", "E", "F", "F", "F", "F", "F", 
"F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", 
"G", "G", "G", "G", "G", "G", "G", "G", "G", "G", "G", "G", "G", 
"G", "G", "G", "G", "G", "H", "H", "H", "H", "H", "H", "H", "H", 
"H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "I", "I", "I", 
"I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", 
"I", "I", "J", "J", "J", "J", "J", "J", "J", "J", "J", "J", "J", 
"J", "J", "J", "J", "J", "J", "J", "A", "B", "C", "D", "E", "F", 
"G", "H", "I", "J"), Opponent = c("B", "B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "D", "D", "D", "D", "D", "D", "D", "D", "D", 
"D", "D", "D", "D", "D", "D", "D", "D", "D", "C", "C", "C", "C", 
"C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", 
"C", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", 
"F", "F", "F", "F", "F", "F", "E", "E", "E", "E", "E", "E", "E", 
"E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "H", "H", 
"H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", 
"H", "H", "H", "G", "G", "G", "G", "G", "G", "G", "G", "G", "G", 
"G", "G", "G", "G", "G", "G", "G", "G", "J", "J", "J", "J", "J", 
"J", "J", "J", "J", "J", "J", "J", "J", "J", "J", "J", "J", "J", 
"I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", 
"I", "I", "I", "I", "I", "B", "A", "D", "C", "F", "E", "H", "G", 
"J", "I"), Line = c("1", "1", "1", "2", "2", "2", "3", "3", "3", 
"4", "4", "4", "x", "x", "x", "x", "x", "x", "1", "1", "1", "2", 
"2", "2", "3", "3", "3", "4", "4", "4", "x", "x", "x", "x", "x", 
"x", "1", "1", "1", "2", "2", "2", "3", "3", "3", "4", "4", "4", 
"x", "x", "x", "x", "x", "x", "1", "1", "1", "2", "2", "2", "3", 
"3", "3", "4", "4", "4", "x", "x", "x", "x", "x", "x", "1", "1", 
"1", "2", "2", "2", "3", "3", "3", "4", "4", "4", "x", "x", "x", 
"x", "x", "x", "1", "1", "1", "2", "2", "2", "3", "3", "3", "4", 
"4", "4", "x", "x", "x", "x", "x", "x", "1", "1", "1", "2", "2", 
"2", "3", "3", "3", "4", "4", "4", "x", "x", "x", "x", "x", "x", 
"1", "1", "1", "2", "2", "2", "3", "3", "3", "4", "4", "4", "x", 
"x", "x", "x", "x", "x", "1", "1", "1", "2", "2", "2", "3", "3", 
"3", "4", "4", "4", "x", "x", "x", "x", "x", "x", "1", "1", "1", 
"2", "2", "2", "3", "3", "3", "4", "4", "4", "x", "x", "x", "x", 
"x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x"), 
Power_Play = c("1", "1", "1", "1", "2", "2", "2", "2", "x", 
"x", "x", "x", "1", "2", "x", "x", "x", "x", "1", "1", "1", 
"1", "2", "2", "2", "2", "x", "x", "x", "x", "1", "2", "x", 
"x", "x", "x", "1", "1", "1", "1", "2", "2", "2", "2", "x", 
"x", "x", "x", "1", "2", "x", "x", "x", "x", "1", "1", "1", 
"1", "2", "2", "2", "2", "x", "x", "x", "x", "1", "2", "x", 
"x", "x", "x", "1", "1", "1", "1", "2", "2", "2", "2", "x", 
"x", "x", "x", "1", "2", "x", "x", "x", "x", "1", "1", "1", 
"1", "2", "2", "2", "2", "x", "x", "x", "x", "1", "2", "x", 
"x", "x", "x", "1", "1", "1", "1", "2", "2", "2", "2", "x", 
"x", "x", "x", "1", "2", "x", "x", "x", "x", "1", "1", "1", 
"1", "2", "2", "2", "2", "x", "x", "x", "x", "1", "2", "x", 
"x", "x", "x", "1", "1", "1", "1", "2", "2", "2", "2", "x", 
"x", "x", "x", "1", "2", "x", "x", "x", "x", "1", "1", "1", 
"1", "2", "2", "2", "2", "x", "x", "x", "x", "1", "2", "x", 
"x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", 
"x"), Projection = c(7.9, 6.4, 4, 4.3, 5.4, 3, 3.1, 3, 4, 
1.6, 0.7, 1.5, 2.5, 2.2, 0, 2.3, 2.2, 0.5, 3, 7, 5.7, 5.1, 
5.6, 4.5, 2.6, 2.6, 2.2, 1.8, 0, 0.1, 1.4, 2.1, 0.9, 0.4, 
1.5, 0.1, 6.1, 5.6, 5.7, 6, 5.7, 4, 2.7, 3.7, 2, 0.8, 0.7, 
1.8, 2.7, 1.1, 2.6, 0.4, 1.8, 2.9, 4.7, 4.9, 4.8, 4.1, 3.6, 
5.3, 3.2, 3.7, 2.4, 1.6, 2, 1.9, 3.4, 1.7, 2.4, 0.6, 0.8, 
1.4, 5.6, 4.8, 7.7, 5.9, 5.6, 3.8, 2.1, 3.5, 3.1, 1.9, 0.8, 
1.9, 1.7, 4, 1.5, 2.5, 0.8, 1.3, 6.7, 3.3, 7.6, 5.4, 5, 5.3, 
3.2, 3.8, 2.7, 0.9, 0.1, 0.9, 2.6, 2.7, 2.3, 1.7, 0, 1.8, 
6.8, 3.3, 6.1, 4.7, 3.8, 6, 3.1, 2.4, 3.7, 0.5, 1.4, 1.5, 
3.1, 3.4, 0.3, 2.6, 3, 1.5, 3.3, 4.5, 6.1, 4.8, 5.5, 3.8, 
2.4, 2.2, 3.8, 0.6, 1.2, 0.8, 3.1, 1.2, 0.8, 0.6, 0.5, 1.8, 
8, 3.3, 7.2, 3.6, 5.8, 5.4, 2.1, 2.6, 2.8, 0.9, 1.7, 1.4, 
1.7, 3.4, 1.9, 2.4, 2.9, 0, 7.5, 7.3, 4.8, 4.5, 5.9, 4.3, 
3.8, 3.6, 2.8, 1.5, 1.4, 2, 2.5, 1.9, 2.3, 1, 2.1, 1.6, 5.3, 
5.7, 4.5, 4.7, 8.7, 8.9, 7.6, 5.2, 6.7, 6.7)), .Names = c("Last.Name", 
"Salary", "Position", "Team", "Opponent", "Line","Power_Play", "Projection"), 
row.names = c(NA, -190L), class = "data.frame")

Это работает со следующим кодом

library("lpSolveAPI")
ncol <- nrow(hockey) # of players 
nteams <- length(unique(hockey$Team))
teams <- unique(hockey$Team)

lpmodel <- make.lp(ncol=(ncol + nteams))
obj_vals <- hockey[, "Projection"]
set.objfn(lpmodel, c(obj_vals, rep(0, nteams))) #dummy 0s for team variable
lp.control(lpmodel,sense='max')
set.type(lpmodel, columns=1:(ncol+nteams), type = "binary")
add.constraint(lpmodel, xt=c(hockey$Salary, rep(0, nteams)), type="<=", rhs=50000)
add.constraint(lpmodel, xt=c(as.numeric(hockey$Position=="C"), rep(0, nteams)), type="=", rhs=2)
add.constraint(lpmodel, xt=c(as.numeric(hockey$Position=="D"), rep(0, nteams)), type="=", rhs=2)
add.constraint(lpmodel, xt=c(as.numeric(hockey$Position=="W"), rep(0, nteams)), type="=", rhs=4)
add.constraint(lpmodel, xt=c(as.numeric(hockey$Position=="G"), rep(0, nteams)), type="=", rhs=1)

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

Теперь я хотел бы добавить некоторые более сложные ограничения, такие как:

  • 8 игроков должны исходить ровно из 3 разных команд

Я сделал несколько попытокэто, но продолжай застрять.Например, это то, что я пробовал для 3 разных команд.В него войдут 3 игрока из 2 команд, но 7-й и 8-й игроки не сгруппированы вместе.

for (i in 1:nteams){
  team <- teams[i]
  add.constraint(lpmodel, lhs=3, xt=c(as.numeric(hockey$Team==team & hockey$Position!='G'), rep(0, i-1), 3, rep(0, nteams-i)), type="<=", rhs=7)
}

# 2 teams 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(lpmodel, xt=c(rep(0, ncol), rep(1, nteams)), type="=", rhs=(nteams-2))
...