使用RGLPK在R中进行Fantasy Football线性规划

9

长期倾听者,第一次向S.O打电话...... 我正在提出一个之前被问过的问题,但是我不认为我聪明到足以解释如何实现这个解决方案,对此我感到抱歉。以下是我发现的问题链接:Constraints in R Multiple Integer Linear Programming

我正在最大化我的预测梦幻得分(FPTS_PREDICT_RF),在保持50000薪资上限的情况下,并且最小化我想出的“风险”计算。

现在,问题出在“flex”位置上。团队需要由9个位置组成, 1 QB 2 RB 3 WR 1 TE 1 DEF 1 FLEX

Flex可以是RB、WR或TE。
那么,我们可以有: 1 QB 2-3 RB 3-4 WR 1-2 TE 1 DEF

我试图实现#RB + #WR + #TE ==7的约束条件。

以下是相关代码:

library(Rglpk)



# number of variables
num.players <- length(final$PLAYER)
# objective:
obj <- final$FPTS_PREDICT_RF
# the vars are represented as booleans
var.types <- rep("B", num.players)
# the constraints
matrix <- rbind(as.numeric(final$position == "QB"), # num QB
           as.numeric(final$position == "RB"), # num RB
           as.numeric(final$position == "WR"), # num WR
           as.numeric(final$position == "TE"), # num TE
           as.numeric(final$position == "DEF"),# num DEF
           diag(final$riskNormalized),         # player's risk
           final$Salary)                       # total cost

direction <- c("==",
         "<=",
         "<=",
         "<=",
         "==",
         rep("<=", num.players),
         "<=")

rhs <- c(1, # Quartbacks
       3, # Running Backs
       2, # Wide Receivers
       1, # Tight Ends
       1, # Defense
       rep(10, num.players), #HERE, you need to enter a number that indicates how
                             #risk you are willing to be, 1 being low risk,
                             # 10 being high risk.  10 is max.
       50000)                # By default, you get 50K to spend, so leave this number alone. 

sol <- Rglpk_solve_LP(obj = obj, mat = matrix, dir = direction, rhs = rhs,
                      types = var.types, max = TRUE)
sol #Projected Fantasy Points

能否有人帮我实现这个约束条件? 非常感谢任何帮助!

编辑:数据集“final”的链接是csv格式: https://www.dropbox.com/s/qp35wc4d380hep1/final.csv?dl=0

附加问题:对于你们中的任何一位幻想足球爱好者,我正在直接从球员历史幻想得分的标准差计算我的“风险”因素,并将此数字归一化到[0,10]的支持上。您能想到更好的方法来计算给定球员的风险吗?


请发布“final”以便您的示例可重现。我认为您需要为#RB> = 2#RB <= 3#WR> = 3#WR <= 4#TE> = 1#TE <= 2添加单独的约束条件,然后#RB +#WR +#TE == 7 - josliber
另外一件事——你的最后一个问题更适合在stats.stackexchange.com上提问。 - josliber
我已经包含了CSV的链接。谢谢您的快速回复,再次抱歉我对这个论坛很幼稚,下次我会在统计学上发布这样的问题。然而,我对如何实现这个约束条件感到困惑。我能够用笔和纸物理地写出一个拉格朗日最大化问题,但是当涉及将其转换为代码时,我很无知。再次感谢! - alpha
你是个好人,查理·布朗。 - alpha
1
@alpha,Dropbox链接已经失效了,你还有那个Excel文件的副本吗?如果可以的话,我很乐意将其上传到其他地方,并为您编辑问题。我的Twitter用户名是@andrewgjohnson。 - Andrew G. Johnson
1个回答

9
您可以通过添加以下约束条件来完成此操作:
  • RB的数量>=2
  • RB的数量<=3
  • WR的数量>=3
  • WR的数量<=4
  • TE的数量>=1
  • TE的数量<=2
  • RB、WR和TE的数量之和等于7
这是更新后的代码:
library(Rglpk)

# number of variables
num.players <- length(final$PLAYER)
# objective:
obj <- final$FPTS_PREDICT_RF
# the vars are represented as booleans
var.types <- rep("B", num.players)
# the constraints
matrix <- rbind(as.numeric(final$position == "QB"), # num QB
           as.numeric(final$position == "RB"), # num RB
           as.numeric(final$position == "RB"), # num RB
           as.numeric(final$position == "WR"), # num WR
           as.numeric(final$position == "WR"), # num WR
           as.numeric(final$position == "TE"), # num TE
           as.numeric(final$position == "TE"), # num TE
           as.numeric(final$position %in% c("RB", "WR", "TE")),  # Num RB/WR/TE
           as.numeric(final$position == "DEF"),# num DEF
           diag(final$riskNormalized),         # player's risk
           final$Salary)                       # total cost
direction <- c("==",
         ">=",
         "<=",
         ">=",
         "<=",
         ">=",
         "<=",
         "==",
         "==",
         rep("<=", num.players),
         "<=")
rhs <- c(1, # Quartbacks
       2, # RB Min
       3, # RB Max
       3, # WR Min
       4, # WR Max
       1, # TE Min
       2, # TE Max
       7, # RB/WR/TE
       1, # Defense
       rep(10, num.players), #HERE, you need to enter a number that indicates how
                             #risk you are willing to be, 1 being low risk,
                             # 10 being high risk.  10 is max.
       50000)                # By default, you get 50K to spend, so leave this number alone. 

sol <- Rglpk_solve_LP(obj = obj, mat = matrix, dir = direction, rhs = rhs,
                      types = var.types, max = TRUE)

最后,您可以通过对final进行子集评估来评估您的解决方案:
final[sol$solution==1,]
#        X          PLAYER FPTS_PREDICT_LIN FPTS_PREDICT_RF Salary position
# 1      1      A.J. Green         20.30647       20.885558   5900       WR
# 17    18    Andre Holmes         13.26369       15.460503   4100       WR
# 145  156 Giovani Bernard         17.05857       19.521157   6100       RB
# 148  160      Greg Olsen         17.08808       17.831687   5500       TE
# 199  222    Jordy Nelson         22.12326       24.077787   7800       WR
# 215  239 Kelvin Benjamin         16.12116       17.132573   5000       WR
# 233  262    Le'Veon Bell         20.51564       18.565763   6300       RB
# 303  340  Ryan Tannehill         17.92518       19.134305   6700       QB
# 362 3641              SD          5.00000        6.388666   2600      DEF
#         risk riskNormalized
# 1   5.131601       3.447990
# 17  9.859006       6.624396
# 145 9.338094       6.274388
# 148 6.517376       4.379111
# 199 9.651055       6.484670
# 215 7.081162       4.757926
# 233 6.900656       4.636641
# 303 4.857983       3.264143
# 362 2.309401       0.000000

针对这个问题,您已经将一个广受欢迎的接收器选为 flex 位置。


有没有想过如何强制将玩家加入阵容?我知道可以通过在模型矩阵中将其清零来删除它们,但不确定如何强制包含。 - tcash21
@tcash21 你可能只需要将 final$PLAYER == "Player Name" 的行通过 rbind 函数加入到 matrix 中,将 direction 加上 "=",并将 rhs 加上 1 - josliber
太棒了,谢谢!这是否类似于使用 lpSolve 的方式? - tcash21
@tcash21 是的,这两个软件包的输入几乎完全相同。 - josliber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接