Выберите ограничение для группировки 2 переменных для одной и той же цели

#python #optaplanner #optapy

#питон #оптический ключ #оптотерапия

Вопрос:

Я пытаюсь добавить constraint_factory, используя OptaPy, вариант OptaPlanner на Python (используя в качестве основы быстрое начало школьного расписания) для планирования спортивных матчей. В каждом матче участвуют 2 команды, поэтому в классе матчей есть 2 переменные : team1 и team2, а также временной интервал и поле.

Как у меня может быть ограничение, при котором я могу вознаграждать или наказывать, если команде (в переменной team1 или team2) было назначено более 2 матчей за день?

Ответ №1:

Я предлагаю подойти к этому по-другому. Начните с Team того , join Match где любая из команд равна, и count() что в a groupBy() . Вам нужно будет добавить составной ключ группы в эту группу в день вашего team и вашего матча.

Вот как такое ограничение будет выглядеть в Java, родном языке OptaPlanner:

 constraintFactory.forEach(Team.class)  .join(Match.class,   Joiners.filtering((team, match) -gt; team == match.team1 || team == match.team2))  .groupBy((team, match) -gt; team,   (team, match) -gt; match.day,   countBi())  .filter((team, day, matchCount) -gt; matchCount gt; 2)  .penalize(..., (team, day, matchCount) -gt; matchCount - 2);  

Должно быть относительно легко получить вариант Python от этого; другой ответ может дать его.

Комментарии:

1. Будет ли это работать, если начать с проблемы (Команды) вместо планирования (Матча) ? Что будет наказано?

2. Не уверен, что понимаю. Да, ограничение будет работать, как показано на рисунке, и вы также можете увидеть штраф в конце. Что я упускаю?

Ответ №2:

Вариант ответа Лукаса на Python:

 from org.optaplanner.core.api.score.stream.ConstraintCollectors import countBi constraint_factory.from_(TeamClass)  # forEach not yet in optapy; will be in next update  .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 gt; 2)   .penalize(..., lambda team, day, matchCount: matchCount - 2)