使用R中的线性(或非线性?)约束来优化值

时间:2013-02-28 23:04:15

标签: r optimization constraints linear-programming

我正在尝试选择最好的幻想足球队,给出不同的限制。我的目标是选择最大化其预计积分总和的玩家

约束是:

1)团队必须包括:

-1 QB

-2 RBs

-2 WRs

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

1 个答案:

答案 0 :(得分:8)

您的约束和目标是线性的,但您的变量是二进制文件:是否应该选择每个玩家。所以你的问题比线性规划(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