微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

lpSolve-“一定不能在一起”约束吗?

如何解决lpSolve-“一定不能在一起”约束吗?

问题

我正在使用lpSolve来找到梦幻棒球队的最佳阵容-一个背包问题,涉及价格SALARY和每个球员DK的投影点PLAYERID在给定的约束下比赛。

当前的代码效果很好,但是我想补充一点,就是我不太清楚。新的限制是在阵容中没有任何球员面对同一阵容中的投手SP之一。

到目前为止,我有什么

我创建了一个名为MNBT(必须不要在一起)的列,该列定义了与每个球员都不能在同一阵容中找到的对方投手的PLAYERID,但我被困在那里。 data.frame slate_players的前20行如下(如果需要,我可以为该特定比赛提供所有91行):

   PLAYERID POS TEAM OPP SALARY    DK TEAM_O    MNBT
1     37584  SP  LAD OAK  10000 18.42    0SP   13170
2     11292  SP  TEX HOU   9300 18.41    0SP 1452665
3   1452665  SP  HOU TEX   7400 15.22    0SP   11292
4     11168  SP  BAL BOS   6900  9.06    0SP   13502
5     13170  SP  OAK LAD   6800  6.06    0SP   37584
6     13502  SP  BOS BAL   6700 13.52    0SP   11168
7   2038873  SP  KCR DET   6600 18.45    0SP   34649
8     34649  SP  DET KCR   6500  7.46    0SP 2038873
9     11446   C  KCR DET   5300  7.55    KCR   34649
10  1054004   C  LAD OAK   5000  8.25    LAD   13170
11    15541   C  BOS BAL   4500  7.08    BOS   11168
12  1252110   C  OAK LAD   4100  5.07    OAK   37584
13    22667   C  BAL BOS   3400  7.09    BAL   13502
14    10290   C  TEX HOU   2900  4.08    TEX 1452665
15    13171   C  DET KCR   2800  5.45    DET 2038873
16    17552   C  HOU TEX   2600  4.47    HOU   11292
17    36727  1B  LAD OAK   5800  9.09    LAD   13170
18    17648  1B  LAD OAK   5400  8.57    LAD   13170
19    17887  1B  OAK LAD   4900  7.30    OAK   37584
20    17851  1B  KCR DET   4400  7.24    KCR   34649
[...]

当前的lpSolve代码

# count the unique players and teams on the slate
unique_teams = unique(slate_players$TEAM_O)
unique_players = unique(slate_players$PLAYERID)

# define the objective for the solver
obj = slate_players$DK

# create a constraint matrix for the solver
con = rbind(t(model.matrix(~ POS + 0,slate_players)),#Positions
            t(model.matrix(~ PLAYERID + 0,#DupPlayers
            t(model.matrix(~ TEAM_O + 0,#SameTeam
            rep(1,nrow(slate_players)),#TotPlayers
            slate_players$SALARY) #MaxSalary

# set the direction for each of the constraints
dir = c("==",#1B
        "==",#2B
        "==",#3B
        "==",#C
        "==",#OF
        "==",#SP
        "==",#SS
        rep('<=',length(unique_players)),#DupPlayers
        rep('<=',length(unique_teams)),#SameTeam
        "==",#TotPlayers
        "<=") #MaxSalary

# set the limits for the right-hand side of the constraints
rhs = c(1,#1B
        1,#2B
        1,#3B
        1,#C
        3,#OF
        2,#SP
        1,#SS
        rep(1,#DupPlayers
        rep(5,#SameTeam
        10,#TotPlayers
        50000) #MaxSalary

# find the optimal solution using the solver
result = lp("max",obj,con,dir,rhs,all.bin = TRUE)

# create a table for the players that are in optimal solution
solindex = which(result$solution==1)
optsolution = slate_players[solindex,]

问题

如何编码此新约束?我一直在手动进行这些调整,但是如果有可以自动执行此过程的解决方案,我将不胜感激。谢谢!

解决方法

虽然这不会为您创建一组约束,但是此示例是@AirSquid可能会帮助您的那些约束之一。

在上面的示例中,第六名玩家(13502)无法与第十三名玩家(22667)对抗。

添加到约束:

c(0,1,0)

添加到路线:

"<="

添加到右侧:

1

下一个技巧是如何在R. Cheerio中生成所有这些约束集。


,

我最后要做的是为每个投手MNBT创建一个帮助者列,而不是单个SP列,以指示他可能不会出现在最佳解决方案中的击球手。在这些列中,我为投手指定了5的值,并为每个击球手不得出现的1分配了值。然后,约束条件变为这些列中每列的总和为<= 5。逻辑是,5击球手最多可能在同一阵容中面对任何单个投手,但是如果在最佳解决方案中出现相同的投手,那么他所面对的击球手都不会有。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。