OptaPy es un solucionador de restricciones de IA para Python para optimizar el problema de rutas de vehículos, la lista de empleados, la programación de mantenimiento, la asignación de tareas, los horarios escolares, la optimización de la nube, la programación de conferencias, la programación de talleres, el embalaje de contenedores y muchos más problemas de planificación.
OptaPy envuelve el motor OptaPlanner internamente, pero usar OptaPy en Python es significativamente más lento que usar OptaPlanner en Java o Kotlin.
Pruebe el cuaderno OptaPy Jupyter.
JAVA_HOME
configurada en el directorio de instalación de JDK. En OptaPy, el dominio tiene tres partes:
Para declarar hechos del problema, utilice el 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 de planificación, utilice el 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
Los decoradores del método @planning_variable
se utilizan para indicar qué campos pueden cambiar. DEBE comenzar con get y tener un método set correspondiente (es decir, get_room(self)
, set_room(self, newRoom)
). El primer parámetro del decorador es el tipo de Variable de planificación (obligatorio). El parámetro value_range_provider_refs
le dice a OptaPlanner de qué proveedores de rango de valores en la solución de planificación puede tomar valores esta variable de planificación.
@planning_id
se utiliza para identificar de forma única un objeto de entidad de una clase particular. Se puede utilizar el mismo ID de planificación en entidades de diferentes clases, pero los ID de todas las entidades de la misma clase deben ser diferentes.
Para declarar la solución de planificación, utilice el 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)
se utiliza para indicar que un método devuelve valores que una variable de planificación puede tomar. Se puede hacer referencia a él por su identificación en el parámetro value_range_provider_refs
de @planning_variable
. También debe tener un @problem_fact_collection_property
o un @planning_entity_collection_property
.
@problem_fact_collection_property(type)
se utiliza para indicar que un método devuelve hechos del problema. El primer parámetro del decorador es el tipo de colección de datos del problema (obligatorio). Debería ser una lista.
@planning_entity_collection_property(type)
se utiliza para indicar que un método devuelve entidades de planificación. El primer parámetro del decorador es el tipo de Colección de Entidades de Planificación (obligatorio). Debería ser una lista.
@planning_score(scoreType)
se utiliza para indicarle a OptaPlanner qué campo contiene la puntuación. El método DEBE comenzar con get y tener un método set correspondiente (es decir, get_score(self)
, set_score(self, score)
). El primer parámetro del decorador es el tipo de puntuación (obligatorio).
Usted define sus restricciones utilizando 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 obtener más detalles 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á una instancia TimeTable
con variables de planificación configuradas para la mejor solución final encontrada.
Para obtener información sobre inicios rápidos, visite el repositorio de inicio rápido de optapy. Para obtener una especificación API completa, visite la documentación de OptaPy.