OptaPy는 차량 경로 문제, 직원 명단 작성, 유지 관리 일정, 작업 할당, 학교 시간표 작성, 클라우드 최적화, 컨퍼런스 일정, 작업장 일정, 빈 포장 및 기타 여러 계획 문제를 최적화하기 위한 Python용 AI 제약 해결사 입니다.
OptaPy는 OptaPlanner 엔진을 내부적으로 래핑하지만 Python에서 OptaPy를 사용하는 것은 Java 또는 Kotlin에서 OptaPlanner를 사용하는 것보다 훨씬 느립니다.
OptaPy Jupyter 노트북을 사용해 보세요.
JAVA_HOME
구성하여 JDK 11 이상을 설치합니다. 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 엔터티를 선언하려면 @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으로 시작해야 하며 해당 설정 메소드(예: get_room(self)
, set_room(self, newRoom)
)가 있어야 합니다. 데코레이터의 첫 번째 매개변수는 계획 변수의 유형입니다(필수). value_range_provider_refs
매개변수는 OptaPlanner에게 이 계획 변수가 값을 가져올 수 있는 계획 솔루션의 값 범위 공급자를 알려줍니다.
@planning_id
는 특정 클래스의 엔터티 개체를 고유하게 식별하는 데 사용됩니다. 동일한 계획 ID를 다른 클래스의 엔터티에 사용할 수 있지만 동일한 클래스에 있는 모든 엔터티의 ID는 달라야 합니다.
Planning Solution을 선언하려면 @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 Entity Collection의 유형입니다(필수). 목록이어야 합니다.
@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 )
Constraint Streams에 대한 자세한 내용은 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 설명서를 방문하세요.