首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >lpSolve -“不能在一起”约束?

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

Stack Overflow用户
提问于 2020-09-25 05:18:09
回答 2查看 171关注 0票数 2

问题

我正在使用lpSolve为一个幻想棒球队寻找最佳阵容-一个背包问题,涉及价格SALARY和预测分数DK的每个球员的PLAYERID在给定的限制比赛。

当前的代码工作得很好,但我有一个限制,我想补充一下,我不太清楚。新的限制是没有任何球员在阵容中面对一个投手SP在同一阵容中。

我到目前为止有什么

我创建了一个名为MNBT (不能在一起)的列,它定义了对方投手的PLAYERID,不能和每个球员的阵容相同,但是我被困在那里了。data.frame slate_players的前20行如下(如果需要,我可以为这个特定的竞赛提供所有91行):

代码语言:javascript
复制
   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代码

代码语言:javascript
复制
# 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, slate_players)), #DupPlayers
            t(model.matrix(~ TEAM_O + 0, slate_players)), #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,length(unique_players)), #DupPlayers
        rep(5,length(unique_teams)), #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,]

问题

如何对这个新约束进行编码?我一直在手动进行这类调整,但是如果有一个解决方案来实现这个过程的自动化,我将非常感激。谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-03 15:23:45

最后,我做的不是一个MNBT列,而是为每个投手SP创建一个助手列,以指示哪些击球手可能不会出现在最优的解决方案中。在这些列中,我为5的投手分配了一个值,为他不能出现的每个击球手分配了一个1值。然后,约束变成了这些列的之和将是<= 5。逻辑是,最大的5击球手可能在同一个阵容中面对任何一个投手,但是如果同一个投手出现在最佳解决方案中,那么他面对的所有击球手都不会是这样。

票数 1
EN

Stack Overflow用户

发布于 2020-10-01 17:58:46

虽然这并不会为您创建一组约束,但这个示例是@AirSquid提到的可能有用的约束之一。

在上面的例子中,第6名玩家(13502)不能与第13名球员(22667)比赛。

添加到约束中:

代码语言:javascript
复制
c(0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0)

在方向上加上:

代码语言:javascript
复制
"<="

在右手边加上:

代码语言:javascript
复制
1

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64058225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档