OptaPy通过groupBy处理同目标双变量实现球队单日场次约束的方法
OptaPy 体育赛事单日球队参赛场次约束编写方案
前置说明
你的Match类的time_slot属性需可获取对应比赛日期,若存储为Python原生datetime对象,取time_slot.date()即可;若为自定义时间段类,替换为对应的日期属性即可。
约束实现代码
from optapy import constraint_provider from optapy.score import HardSoftScore # 替换为你自己项目中Match类的导入路径 from your_module import Match @constraint_provider def event_scheduling_constraints(constraint_factory): return [ # 单日球队参赛超过2场约束 constraint_factory.forEach(Match) # 将每场比赛的两支球队拆分为独立参赛记录,格式为(球队实例, 比赛日期) .flatten_last(lambda match: [ (match.team1, match.time_slot.date), (match.team2, match.time_slot.date) ]) # 按「球队 + 比赛日期」分组,统计对应参赛总场次 .group_by( lambda entry: entry[0], lambda entry: entry[1], lambda entries: len(list(entries)) ) # 过滤出单日参赛超过2场的异常情况 .filter(lambda team, match_date, play_count: play_count > 2) # 配置惩罚规则,可根据需求调整为奖励、修改权重或约束类型 .penalize( "球队单日参赛场次超限", HardSoftScore.ONE_HARD, lambda team, match_date, play_count: play_count - 2 ) ]
参数配置说明
- 约束类型调整:如果该规则仅为优化建议不做强制限制,将
HardSoftScore.ONE_HARD替换为HardSoftScore.ONE_SOFT即可切换为软约束 - 权重调整:可自定义惩罚分数,例如硬约束每次超限罚5分,替换为
HardSoftScore.ofHard(5)即可 - 惩罚逻辑调整:代码中
play_count - 2代表超出几场就惩罚几次,若需固定超限即扣固定分,直接替换为对应数值即可 - 奖励配置:若需对单日参赛≤2场的情况做奖励,可将
filter条件改为play_count <= 2,再将penalize方法替换为reward方法配置对应奖励分数即可
如需实现多级奖惩(例如单日超3场额外加罚),可新增一条独立约束,设置
filter(lambda team, match_date, play_count: play_count > 3)并配置更高的惩罚权重即可。
内容的提问来源于stack exchange,提问作者Hebbs
相关产品推荐
相关产品推荐

