Optapy 要满足的课程约束 - 学校时间表优化
Constraint for curriculum to be met with Optapy - School timetabling optimization
我在 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)
但我仍然有很多未分配的课程。知道如何定义课程约束吗?
所有变量都应该无限制地赋值。它们未分配的唯一原因是:
您正在检查输入问题(所有课程都未分配)而不是从 solver.solve
返回的解决方案(所有课程都应该分配,除非求解器在它之前终止找到了一个可行的解决方案(在这种情况下,应该给求解器更多的时间))。
您将 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
我在 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)
但我仍然有很多未分配的课程。知道如何定义课程约束吗?
所有变量都应该无限制地赋值。它们未分配的唯一原因是:
您正在检查输入问题(所有课程都未分配)而不是从
solver.solve
返回的解决方案(所有课程都应该分配,除非求解器在它之前终止找到了一个可行的解决方案(在这种情况下,应该给求解器更多的时间))。您将
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