我正在用Optapy做一个时间表优化的解决方案。
我正在尝试创建一个链式计划变量,它应该包含链中的多个实体类型。就像这样:
@planning_entity
class Slot:
""" Schedule slot """
def __init__(self):
self.prev_slot = None
@planning_variable(Slot, value_range_provider_refs=['slot_range'],
graph_type=PlanningVariableGraphType.CHAINED)
def get_previous_slot(self):
return self.prev_slot
def set_previous_slot(self, previous_slot: 'Slot'):
self.prev_slot = previous_slot
@planning_entity
class Task(Slot):
""" Allocation to task """
...
@planning_entity
class LunchBreak(Slot):
""" Lunch break """
...由于各种原因,这是行不通的。如果我不向派生类添加任何规划变量,它就会失败,说明我必须这样做,但是如果我将它们添加--我会得到类似于‘赋值错误’之类的java异常。
实际上,是否有可能继承Optapy中的一个@planning_entity类?
发布于 2022-09-05 23:41:15
此代码中的问题是:
@planning_entity
class Slot:
""" Schedule slot """
def __init__(self):
self.prev_slot = None
@planning_variable(Slot, value_range_provider_refs=['slot_range'],
graph_type=PlanningVariableGraphType.CHAINED)
def get_previous_slot(self):
return self.prev_slot
def set_previous_slot(self, previous_slot: 'Slot'):
self.prev_slot = previous_slot由于Python语义,类Slot在它自己的定义过程中不可用。然而,链式模型/子类在光学系统中是可能的。当前版本的optapy (https://github.com/optapy/optapy/issues/101)中存在一个错误,如果@value_range_provider类型与@planning_variable类型不完全匹配,则会引发ClassCastException。这可以通过使用@planning_solution中最派生的超类(在本例中是Slot)来实现。此外,我还将研究链式模型中的多个@planning_entity类的问题。要实现拥有多个规划实体子类(没有新的@planning_variables),以下代码可以工作:
import optapy
from optapy.score import HardSoftScore
from optapy.types import PlanningVariableGraphType
@optapy.problem_fact
class Base:
pass
@optapy.planning_entity
class Slot(Base):
def __init__(self, value=None):
self.value = value
@optapy.planning_variable(Base, value_range_provider_refs=['employee_range', 'task_range', 'lunch_break_range'],
graph_type=PlanningVariableGraphType.CHAINED)
def get_value(self):
return self.value
def set_value(self, value):
self.value = value
@optapy.problem_fact
class Employee(Base): # chained models need an anchor
def __init__(self, code):
self.code = code
@optapy.planning_entity
class Task(Slot):
def __init__(self, code, value=None):
self.code = code
self.value = value
@optapy.planning_entity
class LunchBreak(Slot):
def __init__(self, code, value=None):
self.code = code
self.value = value
@optapy.planning_solution
class Solution:
def __init__(self, employees, tasks, lunch_breaks, score=None):
self.employees = employees
self.tasks = tasks
self.lunch_breaks = lunch_breaks
self.score = score
@optapy.problem_fact_collection_property(Slot)
@optapy.value_range_provider('employee_range')
def get_employees(self):
return self.employees
@optapy.planning_entity_collection_property(Slot)
@optapy.value_range_provider('task_range')
def get_tasks(self):
return self.tasks
@optapy.planning_entity_collection_property(Slot)
@optapy.value_range_provider('lunch_break_range')
def get_lunch_breaks(self):
return self.lunch_breaks
@optapy.planning_score(HardSoftScore)
def get_score(self):
return self.score
def set_score(self, score):
self.score = score
def build_problem():
employees = [
Employee('Amy'),
Employee('Beth')
]
tasks = [
Task('T1'),
Task('T2'),
Task('T3')
]
lunch_breaks = [
LunchBreak('L1'),
LunchBreak('L2')
]
return Solution(employees, tasks, lunch_breaks)并创造出解决者:
import optapy
import optapy.config
from optapy.types import Duration
from domain import Solution, Slot, build_problem
from constraints import define_constraints
solver_config = (optapy.config.solver.SolverConfig()
.withSolutionClass(Solution)
.withEntityClasses(Slot)
.withConstraintProviderClass(define_constraints)
.withTerminationSpentLimit(Duration.ofSeconds(10))
)
solver_factory = optapy.solver_factory_create(solver_config)
solver = solver_factory.buildSolver()
solver.solve(build_problem())https://stackoverflow.com/questions/73597412
复制相似问题