在 Pyomo 中对名册生成模型实施替换约束

问题描述 投票:0回答:1

我正在尝试开发一个 Pyomo 模型,为休闲足球队建立最佳阵容。有 7 个位置 R 需要填补,在任何给定的比赛日,可以有多达 11 名球员 P 来填补这些位置。每个玩家对每个位置都有一个存储在表中的评分。我已经成功实现了一个简单的问题,即为给定的游戏构建最佳名单,并强制执行以下一些约束。

我试图强制执行一些限制或规则:

  • 每个时间段的每个名册位置都必须填补
  • 每个玩家每个时间段只能使用一次
  • 每个玩家必须至少玩一半游戏
  • 时间段定义为四分之一的一半
  • 本节中段守门员位置不可更换
  • 每节必须有一名独特的球员担任守门员(即没有球员在一场比赛中担任守门员两次)
  • 任何给定时间段的总防守评分(两个防守球员评分之和)必须大于指定值

但是,还有一组额外的约束,我很难以这样的方式表述和描述它是一个 LP 问题。

  • 没有球员会连续两个时间段上场(即每节开始时坐在替补席上的球员将在本节中途被替换)
  • 每次季度中期换人,名册位置变化的数量应恰好为 P - R。

换句话说,我试图让替补席上的每个球员在节中都被替换,但不会进行其他位置变化。

后面这些限制是我遇到心理障碍并希望从社区获得一些见解的地方。

评级数据按照这样的格式输入,然后分解为一组元组和字典,以按位置索引其评级。

Example Rating Data

{('Amos', 'CenterMidfield', 1),
 ('Amos', 'Goalie', 1),
 ('Amos', 'LeftDefender', 1),
 ('Amos', 'LeftMidfield', 1),
 ('Amos', 'RightDefender', 1),
 ('Amos', 'RightMidfield', 1),
 ('Amos', 'Striker', 1),
...
 ('Mark', 'CenterMidfield', 9),
 ('Mark', 'Goalie', 10),
 ('Mark', 'LeftDefender', 10),
 ('Mark', 'LeftMidfield', 8),
 ('Mark', 'RightDefender', 10),
 ('Mark', 'RightMidfield', 8),
 ('Mark', 'Striker', 10)}
}

每个季度和半季度索引为(季度,季度_半):

{(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2), (4, 1), (4, 2)}

然后决策变量(为方便起见被截断):

match_allowable_assignments_set:

{(1, 1, 'Amos', 'CenterMidfield'),
 (1, 1, 'Amos', 'Goalie'),
 (1, 1, 'Amos', 'LeftDefender'),
 (1, 1, 'Amos', 'LeftMidfield'),
 (1, 1, 'Amos', 'RightDefender'),
 (1, 1, 'Amos', 'RightMidfield'),
 (1, 1, 'Amos', 'Striker'),
...
 (1, 2, 'Ben', 'CenterMidfield'),
 (1, 2, 'Ben', 'Goalie'),
 (1, 2, 'Ben', 'LeftDefender'),
 (1, 2, 'Ben', 'LeftMidfield'),
 (1, 2, 'Ben', 'RightDefender'),
 (1, 2, 'Ben', 'RightMidfield'),
 (1, 2, 'Ben', 'Striker'),
 ...
 (4, 2, 'Lucas', 'CenterMidfield'),
 (4, 2, 'Lucas', 'Goalie'),
 (4, 2, 'Lucas', 'LeftDefender'),
 (4, 2, 'Lucas', 'LeftMidfield'),
 (4, 2, 'Lucas', 'RightDefender'),
 (4, 2, 'Lucas', 'RightMidfield'),
 (4, 2, 'Lucas', 'Striker'),
 (4, 2, 'Mark', 'CenterMidfield'),
 (4, 2, 'Mark', 'Goalie'),
 (4, 2, 'Mark', 'LeftDefender'),
 (4, 2, 'Mark', 'LeftMidfield'),
 (4, 2, 'Mark', 'RightDefender'),
 (4, 2, 'Mark', 'RightMidfield'),
 (4, 2, 'Mark', 'Striker')}

为了完整性,模型是用这个目标函数实例化的(为了简洁起见,我省略了约束代码):

model = pyo.ConcreteModel()
model.x = pyo.Var(match_allowable_assignments_set, within=pyo.Binary ,initialize=1)

model.obj = pyo.Objective(
    expr = sum(player_rating_dict[player][pos]*model.x[(quarter,quarter_half,player,pos)] for (quarter,quarter_half,player,pos) in match_allowable_assignments_set ), 
    sense = pyo.maximize )
python optimization linear-programming pyomo
1个回答
0
投票

我认为你想做这样的事情:

∑(pos) play[t, player, pos] >= 1 - ∑(pos) play[t-1, player, pos]

对于所有人

t
>
t.first()
t
ε
time periods

对于所有人

player
ε
players

这基本上强制要求每个球员如果在上一时期没有担任任何位置,则必须在每个时期担任某个位置

© www.soinside.com 2019 - 2024. All rights reserved.