OptaPy 对同一目标的 groupBy 2 个变量的约束
OptaPy Constraint to groupBy 2 variables for the same target
我正在尝试使用 OptaPy(OptaPlanner 的 Python 变体)添加 constraint_factory(使用学校时间表快速入门作为基础)来安排体育比赛。每场比赛有 2 支球队,因此比赛 class 中有 2 个变量:team1 和 team2 以及 time_slot 和 pitch.
如果一个团队(在 team1 或 team2 变量中)在一天内被分配了超过 2 场比赛,我如何设置奖励或惩罚的约束?
我建议以不同的方式处理它。从 Team
、join
和 Match
开始,其中任何一支队伍都相等,而 count()
在 groupBy()
中。您将需要在该 groupBy、您的 team
和您的比赛日中添加复合组键。
在 OptaPlanner 的母语 Java 中,这样的约束是这样的:
constraintFactory.forEach(Team.class)
.join(Match.class,
Joiners.filtering((team, match) -> team == match.team1 || team == match.team2))
.groupBy((team, match) -> team,
(team, match) -> match.day,
countBi())
.filter((team, day, matchCount) -> matchCount > 2)
.penalize(..., (team, day, matchCount) -> matchCount - 2);
从中获得 Python 变体应该相对容易;另一个答案可能会提供它。
Python 卢卡斯答案的变体:
from org.optaplanner.core.api.score.stream.ConstraintCollectors import countBi
constraint_factory.forEach(TeamClass)
.join(MatchClass,
Joiners.filtering(lambda team, match: team == match.team1 or team == match.team2)) \
.groupBy(lambda team, match: team,
lambda team, match: match.day,
countBi()) \
.filter(lambda team, day, matchCount: matchCount > 2) \
.penalize(..., lambda team, day, matchCount: matchCount - 2)
我正在尝试使用 OptaPy(OptaPlanner 的 Python 变体)添加 constraint_factory(使用学校时间表快速入门作为基础)来安排体育比赛。每场比赛有 2 支球队,因此比赛 class 中有 2 个变量:team1 和 team2 以及 time_slot 和 pitch.
如果一个团队(在 team1 或 team2 变量中)在一天内被分配了超过 2 场比赛,我如何设置奖励或惩罚的约束?
我建议以不同的方式处理它。从 Team
、join
和 Match
开始,其中任何一支队伍都相等,而 count()
在 groupBy()
中。您将需要在该 groupBy、您的 team
和您的比赛日中添加复合组键。
在 OptaPlanner 的母语 Java 中,这样的约束是这样的:
constraintFactory.forEach(Team.class)
.join(Match.class,
Joiners.filtering((team, match) -> team == match.team1 || team == match.team2))
.groupBy((team, match) -> team,
(team, match) -> match.day,
countBi())
.filter((team, day, matchCount) -> matchCount > 2)
.penalize(..., (team, day, matchCount) -> matchCount - 2);
从中获得 Python 变体应该相对容易;另一个答案可能会提供它。
Python 卢卡斯答案的变体:
from org.optaplanner.core.api.score.stream.ConstraintCollectors import countBi
constraint_factory.forEach(TeamClass)
.join(MatchClass,
Joiners.filtering(lambda team, match: team == match.team1 or team == match.team2)) \
.groupBy(lambda team, match: team,
lambda team, match: match.day,
countBi()) \
.filter(lambda team, day, matchCount: matchCount > 2) \
.penalize(..., lambda team, day, matchCount: matchCount - 2)