在Pyomo中为足球阵容生成模型制定换人约束
业余足球队最优阵容Pyomo模型约束转化问题
我正在开发一个Pyomo模型,用于给业余足球队生成最优阵容。目前设定是:需要填补7个位置(记为R),比赛当日最多可用11名球员(记为P)。每名球员在各个位置的评分已整理成表格,后续会拆分为元组集合和字典来按位置索引评分。
基础模型已完成,且已添加以下约束:
- 每个时间段的所有阵容位置必须填满
- 每名球员在单个时间段内只能出场一次
- 每名球员至少要参赛半场时长
- 时间段定义为四分之一场的一半
- 门将位置不能在节中换人
- 每节必须由不同的球员担任门将(单场比赛中无球员两次担任门将)
- 任意时间段的总防守评分(两名防守球员评分之和)必须大于指定值
现在我卡在两组约束的线性规划(LP)形式转化上,这两组约束是:
- 没有球员会连续两个时间段坐替补席(即节初坐替补的球员必须在节中被换上场)
- 每次节中换人时,阵容位置变动的数量必须恰好为P-R(换句话说,节中替补席上的所有球员都要被换上场,且不做其他位置调整)
评分数据输入格式
评分数据会被拆分为元组集合和字典,示例如下:
{('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)}
时间段索引
每节和半节的索引为(quarter, quarter_half),集合如下:
{(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')}
目标函数
模型目标函数实例化代码如下:
import pyomo.environ as pyo 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 )
内容的提问来源于stack exchange,提问作者LazyCoder1982
相关产品推荐
相关产品推荐

