OptaPy é um solucionador de restrições de IA para Python para otimizar problemas de roteamento de veículos, escalação de funcionários, agendamento de manutenção, atribuição de tarefas, cronograma escolar, otimização de nuvem, agendamento de conferências, agendamento de oficinas, empacotamento de caixas e muitos outros problemas de planejamento.
O OptaPy envolve o mecanismo OptaPlanner internamente, mas usar o OptaPy em Python é significativamente mais lento do que usar o OptaPlanner em Java ou Kotlin.
Experimente o notebook OptaPy Jupyter.
JAVA_HOME
configurada no diretório de instalação do JDK. No OptaPy, o domínio tem três partes:
Para declarar fatos do problema, use o decorador @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
Para declarar Entidades do Planning, use o decorador @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
Os decoradores do método @planning_variable
são usados para indicar quais campos podem ser alterados. DEVE começar com get e ter um método set correspondente (ou seja, get_room(self)
, set_room(self, newRoom)
). O primeiro parâmetro do decorador é o tipo da Variável de Planejamento (obrigatório). O parâmetro value_range_provider_refs
informa ao OptaPlanner de quais provedores de intervalo de valores na Solução de Planejamento esta Variável de Planejamento pode obter valores.
@planning_id
é usado para identificar exclusivamente um objeto de entidade de uma classe específica. O mesmo ID de Planejamento pode ser utilizado em entidades de classes diferentes, mas os IDs de todas as entidades da mesma classe devem ser diferentes.
Para declarar a Solução de Planejamento, use o decorador @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)
é usado para indicar que um método retorna valores que uma variável de planejamento pode assumir. Ele pode ser referenciado por seu id no parâmetro value_range_provider_refs
de @planning_variable
. Também deve ter um @problem_fact_collection_property
ou um @planning_entity_collection_property
.
@problem_fact_collection_property(type)
é usado para indicar que um método retorna fatos do problema. O primeiro parâmetro do decorador é o tipo de Coleção de Fatos do Problema (obrigatório). Deveria ser uma lista.
@planning_entity_collection_property(type)
é usado para indicar que um método retorna Entidades de Planejamento. O primeiro parâmetro do decorador é o tipo de Coleção de Entidades de Planejamento (obrigatório). Deveria ser uma lista.
@planning_score(scoreType)
é usado para informar ao OptaPlanner qual campo contém a pontuação. O método DEVE começar com get e ter um método set correspondente (ou seja, get_score(self)
, set_score(self, score)
). O primeiro parâmetro do decorador é o tipo de pontuação (obrigatório).
Você define suas restrições usando 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 )
para obter mais detalhes sobre Constraint Streams, consulte 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
será uma instância TimeTable
com variáveis de planejamento definidas para a melhor solução final encontrada.
Para obter início rápido, visite o repositório de início rápido optapy. Para obter especificações completas da API, visite a documentação do OptaPy.