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 文件。