python 中的 OptaPy isEqual isNotEqual

OptaPy isEqual isNotEqual in python

我正在尝试将体育比赛安排到时间段中,并且希望白天没有空的时间段(所以尽早结束)。我认为 isEqual 和 isNotEqual 应该有所帮助,但停留在 Python 版本的语法中。我想我已经接近了(下面的相关代码)

在domain.py

@problem_fact
class Timeslot:
    def __init__(self, id, match_date, date_str, start_time, end_time):
        self.id = id
        self.match_date = match_date
        self.date_str = date_str # java does not have date or datetime equivalent so str also needed
        self.start_time = start_time
        self.end_time = end_time

    @planning_id
    def get_id(self):
        return self.id

    def __str__(self):
        return (
                f"Timeslot("
                f"id={self.id}, "
                f"match_date={self.match_date}, "
                f"date_str={self.date_str}, "
                f"start_time={self.start_time}, "
                f"end_time={self.end_time})"

在constraints.py

def fill_pitches_from_start(constraint_factory):
    # A pitch should not be empty if possible
    return constraint_factory \
        .from_(TimeslotClass).ifNotExists(MatchClass, Joiners.equal(Timeslot.get_id(), Match.get_timeslot() ) )  \
        .join(TimeslotClass).ifExists(MatchClass, Joiners.equal(Timeslot.get_id(), Match.get_timeslot())) \
        .filter(lambda slot1, slot2: datetime.combine(slot1.date_str, slot1.timeslot.start_time) < datetime.combine(slot2.date_str, slot2.start_time) ) \
        .penalize("Pitch Empty with Later pitches populated", HardSoftScore.ofSoft(10))

这会产生预期的错误: 类型错误:get_id() 缺少 1 个必需的位置参数:'self'

但我无法计算出正确的语法 - 也许使用 lambda?

你很亲密;这应该有效:

def fill_pitches_from_start(constraint_factory):
# A pitch should not be empty if possible
return constraint_factory \
    .forEach(TimeslotClass).ifNotExists(MatchClass, Joiners.equal(lambda timeslot: timeslot.get_id(), lambda match: match.get_timeslot() ) )  \
    .join(TimeslotClass).ifExists(MatchClass, Joiners.equal(lambda timeslot1, timeslot2: timeslot2.get_id(), lambda match: match.get_timeslot())) \
    .filter(lambda slot1, slot2: datetime.combine(slot1.date_str, slot1.timeslot.start_time) < datetime.combine(slot2.date_str, slot2.start_time) ) \
    .penalize("Pitch Empty with Later pitches populated", HardSoftScore.ofSoft(10))

它可能可以使用 Joiners.lessThan 进行改进,但这需要先更新到 optapy,以便 Joiners 可以使用任何 Python 类型。 (将在更新 optapy 以支持所述功能时更新此答案)。