【问题标题】:Constraint for curriculum to be met with Optapy - School timetabling optimizationOptapy 满足课程限制 - 学校时间表优化
【发布时间】:2022-08-20 16:25:58
【问题描述】:

我在 python 中使用 Optapy 库,我想添加需要满足​​课程的约束,因为我现在得到了许多未分配的课程,即使大部分时间段和房间都是空的,而且教师资源大多未使用。 我尝试添加以下约束:

def curriculum_needs_to_be_met(constraint_factory):
return constraint_factory \\
    .forEach(LessonClass) \\
    .filter(lambda lesson: lesson.timeslot is None) \\
    .penalize(\"Curriculum needs to be met\", HardSoftScore.ONE_HARD)

但我仍然得到许多未分配的课程。知道如何定义课程限制吗?

    标签: python optapy


    【解决方案1】:

    所有变量都应该在没有约束的情况下分配。它们未被分配的唯一原因是:

    1. 您正在检查输入问题(未分配所有课程)而不是从 solver.solve 返回的解决方案(应分配所有课程,除非求解器在找到可行的解决方案之前终止(在这种情况下,求解器应该给予更多的时间))。

    2. 您将nullable=True 传递给@planning_variable(即域如下所示):

       @planning_entity
       class Lesson:
           def __init__(self, id, subject, teacher, student_group, timeslot=None, room=None):
               self.id = id
               self.subject = subject
               self.teacher = teacher
               self.student_group = student_group
               self.timeslot = timeslot
               self.room = room
      
           @planning_id
           def get_id(self):
               return self.id
      
           @planning_variable(Timeslot, ["timeslotRange"], nullable=True)
           def get_timeslot(self):
               return self.timeslot
      
           def set_timeslot(self, new_timeslot):
               self.timeslot = new_timeslot
      
           # ...
      

      如果您想允许变量采用 None 值,您可以这样做。但是,情况可能并非如此,因为您不希望变量采用 None 值。

      因此,我会仔细检查您使用的是解决方案而不是问题。如果您正在使用该解决方案并且仍然看到未分配的值,那么我会更新它的 TerminationConfiguration 以给它更多时间。有关终止配置的示例,请参阅 OptaPlanner 文档:https://www.optaplanner.org/docs/optaplanner/latest/optimization-algorithms/optimization-algorithms.html#termination;您可以像这样在 OptaPy 中创建新的终止配置:

      import optapy.config
      termination = optapy.config.solver.termination.TerminationConfig()
      termination.setBestScoreFeasible(True) # keep solving until the solution feasible
      solver_config = optapy.config.solver.SolverConfig() \
          .withTerminationConfig(termination) \
      # rest of SolverConfig setup
      

    【讨论】:

    • 它确实奏效了。正如您所写,我必须设置终止持续时间。我得到了一个可行的解决方案,但是除了我可能得到的可行解决方案之外,我如何定义目标函数。例如,我想尽量减少我使用的房间或教师资源,因为我为此支付租金或工资,或者尽量减少一天中房间/教师的空闲时间
    • 目标函数是您的约束。特别是,硬约束定义什么是可行的,软约束定义你想要/不想要的解决方案。您可以添加一个软约束来计算使用的教师/房间的数量。一般来说,给予求解器的时间越多,找到的解就越好。由您决定给求解器多少时间。在大多数情况下,由于搜索空间巨大,找到最优解是不切实际的,因此使用在分配的时间内找到的最优解来代替。
    • 我明白。如果算法找到两个具有相同数量的破坏软约束的可行解决方案(即破坏 5 个软约束),将选择哪一个?是否可以为此定义一个标准?您知道如何在算法检查的每个解决方案中计算房间/教师的数量,并添加限制房间/教师数量的约束吗?
    • 它不是基于破坏约束的数量,而是基于解决方案的分数。例如,在 VRP 中,路线的长度受到惩罚,但(通常)每条路线只有一个约束“被破坏”。要计算“房间/教师”,我会做类似constraint_factory.forEach(LessonClass).groupBy(lambda lesson: lesson.teacher).penalize("Minimize used teachers", HardSoftScore.ONE_SOFT) 的事情(将 groupBy 中的 lambda 更改为对房间做类似的事情);此约束为“对于至少一堂课引用的每位教师,惩罚一堂课”。
    • 如果两个解决方案具有相同的分数,则将使用 OptaPlanner 找到的第一个解决方案(只有在找到具有更好分数的新解决方案时才会更改最佳解决方案)。
    【解决方案2】:

    我使用 optapy 库来组织学校时间表,但是当链接到数据库时,它在一行上运行只获取最后一个值并打印它。?

    【讨论】:

      猜你喜欢
      • 2019-02-11
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      • 1970-01-01
      • 2018-07-15
      • 2019-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多