【问题标题】:Optimize value with linear (or non-linear?) constraints in R在 R 中使用线性(或非线性?)约束优化值
【发布时间】:2013-02-15 08:15:38
【问题描述】:

考虑到不同的限制条件,我正在努力挑选最好的梦幻足球队。我的目标是挑选能够最大化他们的投影总和的玩家

约束是:

1) 团队必须包括:

-1 四分卫

-2 RB

-2 WR

-1 TE

2) 玩家的风险不得超过 6

3) 玩家的费用总和不得超过300。

我该怎么做? R 中优化这些约束的最佳包/功能是什么?给定这些约束,最大化投影点的函数调用会是什么样子?仅供参考,我将搜索 100-300 名玩家。

提前致谢!这是一个小的示例数据集:

name <- c("Aaron Rodgers","Tom Brady","Arian Foster","Ray Rice","LeSean McCoy","Calvin Johnson","Larry Fitzgerald","Wes Welker","Rob Gronkowski","Jimmy Graham")

pos <- c("QB","QB","RB","RB","RB","WR","WR","WR","TE","TE")

pts <- c(167, 136, 195, 174, 144, 135, 89, 81, 114, 111) 

risk <- c(2.9, 3.4, 0.7, 1.1, 3.5, 5.0, 6.7, 4.7, 3.7, 8.8) 

cost <- c(60, 47, 63, 62, 40, 60, 50, 35, 40, 40) 

mydata <- data.frame(name, pos, pts, risk, cost) 

【问题讨论】:

  • 欢迎来到 SO。 :-) 你已经尝试过什么?这是一个有趣的问题,但这里的人们会希望看到你已经尝试过将某些东西放在一起。代码行开头的 4 个空格也将其格式化为代码块。
  • 你打算搜索所有玩家吗?您想搜索多少个玩家?对于您的示例,只有 2*3*3*2=36 个团队。但如果有 100 名玩家,则可能有大约 20*20*(30*29/2)*(30*29)/2=7590000 支队伍。
  • 嗨,西蒙和赛斯,谢谢。我可以使用 Excel 的求解器函数进行此优化,但我不熟悉如何在 R 中进行线性优化。我看到有很多不同的函数,但我不确定哪个最相关我的问题类型,我没有在 R 中为优化函数编写参数的经验。任何帮助将不胜感激。顺便说一句,我正在搜索大约 100-300 名玩家。
  • 这似乎是一个很好的例子:fishyoperations.com/r/…
  • @dadrivr 如果它充分解决了您的问题,请不要忘记接受 Flodel 的回复。您可以通过检查响应旁边的勾号来做到这一点。这是“奖励”受访者帮助您的时间的一种小方法。

标签: r optimization constraints linear-programming


【解决方案1】:

你的约束和目标是线性的,但你的变量是二元的:每个球员是否应该被选中。所以你的问题比线性规划(LP)更普遍,它是混合整数规划(MIP)。在 CRAN 的 Optimization Task View 上,查找他们的 MIP 部分。

CPLEX 是您可能无法访问的商业求解器,但 GLPK 是免费的。如果我是你,我可能会选择高级接口Rglpk

这需要你把你的问题用矩阵的形式表达出来,我建议你看看文档和例子。


编辑:这是一个实现:

# We are going to solve:
# maximize f'x subject to A*x <dir> b
# where:
#   x is the variable to solve for: a vector of 0 or 1:
#     1 when the player is selected, 0 otherwise,
#   f is your objective vector,
#   A is a matrix, b a vector, and <dir> a vector of "<=", "==", or ">=",
#   defining your linear constraints.

# number of variables
num.players <- length(name)
# objective:
f <- pts
# the variable are booleans
var.types <- rep("B", num.players)
# the constraints
A <- rbind(as.numeric(pos == "QB"), # num QB
           as.numeric(pos == "RB"), # num RB
           as.numeric(pos == "WR"), # num WR
           as.numeric(pos == "TE"), # num TE
           diag(risk),              # player's risk
           cost)                    # total cost

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

b <- c(1,
       2,
       2,
       1,
       rep(6, num.players),
       300)

library(Rglpk)
sol <- Rglpk_solve_LP(obj = f, mat = A, dir = dir, rhs = b,
                      types = var.types, max = TRUE)
sol
# $optimum
# [1] 836                      ### <- the optimal total points

# $solution
#  [1] 1 0 1 0 1 1 0 1 1 0     ### <- a `1` for the selected players

# $status
# [1] 0                        ### <- an optimal solution has been found

# your dream team
name[sol$solution == 1]
# [1] "Aaron Rodgers"  "Arian Foster"   "LeSean McCoy"
# [4] "Calvin Johnson" "Wes Welker"     "Rob Gronkowski

【讨论】:

  • 这真的很棒而且很有帮助。唯一似乎缺少的是玩家成本总和应小于 300 的约束。现在,解决方案的成本是 320。似乎设置了“dir”和“b”矩阵为约束正确设置,但“A”矩阵的最后一行不是。我尝试将其更改为:diag(cost),但这不起作用。我们希望它只反映选定玩家的总和。如何修改 A 矩阵的最后一行来实现这一点?非常感谢——这看起来很棒!
  • @dadrivr:抱歉,现在已修复,A 的最后一行需要为cost。最终费用为sum(cost * sol$solution): 298。
猜你喜欢
  • 1970-01-01
  • 2014-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多