OptaPy 是Python 的人工智能约束求解器,可优化车辆路线问题、员工排班、维护计划、任务分配、学校时间表、云优化、会议安排、作业车间调度、装箱和更多规划问题。
OptaPy 在内部包装了 OptaPlanner 引擎,但在 Python 中使用 OptaPy 比在 Java 或 Kotlin 中使用 OptaPlanner 慢得多。
尝试 OptaPy Jupyter 笔记本。
JAVA_HOME
配置为JDK安装目录。 在 OptaPy 中,域由三部分组成:
要声明问题事实,请使用@problem_fact
装饰器
from optapy import problem_fact
@ problem_fact
class Timeslot :
def __init__ ( self , id , day_of_week , start_time , end_time ):
self . id = id
self . day_of_week = day_of_week
self . start_time = start_time
self . end_time = end_time
要声明规划实体,请使用@planning_entity
装饰器
from optapy import planning_entity , planning_id , 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 , value_range_provider_refs = [ "timeslotRange" ])
def get_timeslot ( self ):
return self . timeslot
def set_timeslot ( self , new_timeslot ):
self . timeslot = new_timeslot
@ planning_variable ( Room , value_range_provider_refs = [ "roomRange" ])
def get_room ( self ):
return self . room
def set_room ( self , new_room ):
self . room = new_room
@planning_variable
方法装饰器用于指示哪些字段可以更改。必须以 get 开头并具有相应的 set 方法(即get_room(self)
、 set_room(self, newRoom)
)。装饰器的第一个参数是规划变量的类型(必需)。 value_range_provider_refs
参数告诉 OptaPlanner 此规划变量可以从规划解决方案上的哪些值范围提供程序获取值。
@planning_id
用于唯一标识特定类的实体对象。不同类的实体可以使用相同的Planning Id,但同一类的所有实体的id必须不同。
要声明规划解决方案,请使用@planning_solution
装饰器
from optapy import planning_solution , problem_fact_collection_property , value_range_provider , planning_entity_collection_property , planning_score
@ planning_solution
class TimeTable :
def __init__ ( self , timeslot_list , room_list , lesson_list , score = None ):
self . timeslot_list = timeslot_list
self . room_list = room_list
self . lesson_list = lesson_list
self . score = score
@ problem_fact_collection_property ( Timeslot )
@ value_range_provider ( range_id = "timeslotRange" )
def get_timeslot_list ( self ):
return self . timeslot_list
@ problem_fact_collection_property ( Room )
@ value_range_provider ( range_id = "roomRange" )
def get_room_list ( self ):
return self . room_list
@ planning_entity_collection_property ( Lesson )
def get_lesson_list ( self ):
return self . lesson_list
@ planning_score ( HardSoftScore )
def get_score ( self ):
return self . score
def set_score ( self , score ):
self . score = score
@value_range_provider(range_id)
用于指示方法返回计划变量可以采用的值。可以通过@planning_variable
的value_range_provider_refs
参数中的 id 来引用它。它还应该有一个@problem_fact_collection_property
或@planning_entity_collection_property
。
@problem_fact_collection_property(type)
用于指示方法返回问题事实。装饰器的第一个参数是问题事实集合的类型(必需)。它应该是一个列表。
@planning_entity_collection_property(type)
用于指示方法返回规划实体。装饰器的第一个参数是规划实体集合的类型(必需)。它应该是一个列表。
@planning_score(scoreType)
用于告诉 OptaPlanner 哪个字段保存分数。该方法必须以 get 开头,并具有相应的 set 方法(即get_score(self)
、 set_score(self, score)
)。装饰器的第一个参数是分数类型(必需)。
您可以使用 ConstraintFactory 定义约束
from domain import Lesson
from optapy import constraint_provider
from optapy . types import Joiners , HardSoftScore
@ constraint_provider
def define_constraints ( constraint_factory ):
return [
# Hard constraints
room_conflict ( constraint_factory ),
# Other constraints here...
]
def room_conflict ( constraint_factory ):
# A room can accommodate at most one lesson at the same time.
return constraint_factory . for_each_unique_pair ( Lesson ,
# ... in the same timeslot ...
Joiners . equal ( lambda lesson : lesson . timeslot ),
# ... in the same room ...
Joiners . equal ( lambda lesson : lesson . room ))
. penalize ( "Room conflict" , HardSoftScore . ONE_HARD )
有关约束流的更多详细信息,请参阅 https://www.optaplanner.org/docs/optaplanner/latest/constraint-streams/constraint-streams.html
from optapy import solver_factory_create
from optapy . types import SolverConfig , Duration
from constraints import define_constraints
from domain import TimeTable , Lesson , generate_problem
solver_config = SolverConfig (). withEntityClasses ( Lesson )
. withSolutionClass ( TimeTable )
. withConstraintProviderClass ( define_constraints )
. withTerminationSpentLimit ( Duration . ofSeconds ( 30 ))
solver = solver_factory_create ( solver_config ). buildSolver ()
solution = solver . solve ( generate_problem ())
solution
将是一个TimeTable
实例,其中计划变量设置为找到的最终最佳解决方案。
如需快速入门,请访问 optapy 快速入门存储库。有关完整的 API 规范,请访问 OptaPy 文档。