All Projects → optapy → optapy

optapy / optapy

Licence: Apache-2.0 license
OptaPy is an AI constraint solver for Python to optimize planning and scheduling problems.

Programming Languages

python
139335 projects - #7 most used programming language
java
68154 projects - #9 most used programming language
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to optapy

Optaplanner
AI constraint solver in Java to optimize the vehicle routing problem, employee rostering, task assignment, maintenance scheduling, conference scheduling and other planning problems.
Stars: ✭ 2,454 (+1369.46%)
Mutual labels:  vehicle-routing-problem, local-search, simulated-annealing, tabu-search, metaheuristics, employee-rostering, traveling-salesman-problem, mathematical-optimization
Ascension
A metaheuristic optimization framework
Stars: ✭ 24 (-85.63%)
Mutual labels:  local-search, simulated-annealing, tabu-search, metaheuristics
VRPTW
Solving VRPTW with metaheuristics
Stars: ✭ 27 (-83.83%)
Mutual labels:  vehicle-routing-problem, local-search, metaheuristics
VeRyPy
A python library with implementations of 15 classical heuristics for the capacitated vehicle routing problem.
Stars: ✭ 166 (-0.6%)
Mutual labels:  vehicle-routing-problem, traveling-salesman-problem
pigosat
Go (golang) bindings for Picosat, the satisfiability solver
Stars: ✭ 15 (-91.02%)
Mutual labels:  np-hard, np-complete
KnapsackFX
Solving Knapsack 0/1 problem with various Local Search algorithms like Hill Climbing, Genetic Algorithms, Simulated Annealing, Tabu Search
Stars: ✭ 25 (-85.03%)
Mutual labels:  simulated-annealing, tabu-search
tabu search-vrpcd
A Tabu Search algorithm for the Vehicle Routing Problem with Cross-Docking.
Stars: ✭ 34 (-79.64%)
Mutual labels:  vehicle-routing-problem, tabu-search
AntColonyOptimization-TSP
An Ant Colony Optimization algorithm for the Traveling Salesman Problem
Stars: ✭ 29 (-82.63%)
Mutual labels:  np-complete
sopt
sopt:A simple python optimization library
Stars: ✭ 42 (-74.85%)
Mutual labels:  simulated-annealing
paradiseo
An evolutionary computation framework to (automatically) build fast parallel stochastic optimization solvers
Stars: ✭ 73 (-56.29%)
Mutual labels:  metaheuristics
AI-Programming-using-Python
This repository contains implementation of different AI algorithms, based on the 4th edition of amazing AI Book, Artificial Intelligence A Modern Approach
Stars: ✭ 43 (-74.25%)
Mutual labels:  simulated-annealing
Multiple-Vehicle-Routing
Simple MVR simulation
Stars: ✭ 27 (-83.83%)
Mutual labels:  vehicle-routing-problem
TravelingSalesmanHeuristics.jl
Julia package for simple traveling salesman problem heuristics
Stars: ✭ 46 (-72.46%)
Mutual labels:  traveling-salesman-problem
Harris-Hawks-Optimization-Algorithm-and-Applications
Source codes for HHO paper: Harris hawks optimization: Algorithm and applications: https://www.sciencedirect.com/science/article/pii/S0167739X18313530. In this paper, a novel population-based, nature-inspired optimization paradigm is proposed, which is called Harris Hawks Optimizer (HHO).
Stars: ✭ 31 (-81.44%)
Mutual labels:  metaheuristics
VRPTW-ga
Vehicle Routing Problem with Time Windows - Genetic Algorithm solution with Python
Stars: ✭ 40 (-76.05%)
Mutual labels:  vehicle-routing-problem
minisat-rust
Experimental minisat SAT solver reimplementation in Rust
Stars: ✭ 68 (-59.28%)
Mutual labels:  np-complete
tsplib95
Library for working with TSPLIB files.
Stars: ✭ 48 (-71.26%)
Mutual labels:  traveling-salesman-problem
Metaheuristics.jl
High-performance metaheuristics for optimization coded purely in Julia.
Stars: ✭ 144 (-13.77%)
Mutual labels:  simulated-annealing
automile-php
Automile offers a simple, smart, cutting-edge telematics solution for businesses to track and manage their business vehicles.
Stars: ✭ 28 (-83.23%)
Mutual labels:  vehicle-routing-problem
MathOptSetDistances.jl
Distances to sets for MathOptInterface
Stars: ✭ 24 (-85.63%)
Mutual labels:  mathematical-optimization

OptaPy

PyPI Binder

OptaPy is an AI constraint solver for Python to optimize the Vehicle Routing Problem, Employee Rostering, Maintenance Scheduling, Task Assignment, School Timetabling, Cloud Optimization, Conference Scheduling, Job Shop Scheduling, Bin Packing and many more planning problems.

Questions? Ask us on StackOverflow. Found an issue? Report it here.

OptaPy wraps the OptaPlanner engine internally, so it needs a JDK installed.

Warning
OptaPy is an experimental technology. It is at least 20 times slower than using OptaPlanner in Java or Kotlin.

Looking for Quickstarts?

OptaPy’s quickstarts have moved to the optapy-quickstarts repository.

Get started

This quickstart uses OptaPy to optimize a school timetable for student and teachers.

Jupyter notebook

Instead of going through this tutorial, you can also follow along in the OptaPy Jupyter notebook.

Prerequisites

  1. Install Python 3.9 or later.

  2. Install JDK 11 or later with the environment variable JAVA_HOME configured to the JDK installation directory.

Installing

pip install optapy

Source code overview

Domain

In OptaPy, the domain has three parts:

  • Problem Facts, which do not change

  • Planning Entities, which have one or more planning variables

  • Planning Solution, which define the facts and entities of the problem

Problem Facts

To declare Problem Facts, use the @problem_fact decorator

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 Entities

To declare Planning Entities, use the @planning_entity decorator

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 = newRoom
  • @planning_variable method decorators are used to indicate what fields can change. The method MUST begin with get and have a corresponding set method (i.e. get_room(self), set_room(self, newRoom)). The first parameter of the decorator is the type of the Planning Variable (required). The value_range_provider_refs parameter tells OptaPlanner what value range providers on the Planning Solution this Planning Variable can take values from.

  • @planning_id is used to uniquely identify an entity object of a particular class. The same Planning Id can be used on entities of different classes, but the ids of all entities in the same class must be different.

Planning Solution

To declare the Planning Solution, use the @planning_solution decorator

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) is used to indicate a method returns values a Planning Variable can take. It can be referenced by its id in the value_range_provider_refs parameter of @planning_variable. It should also have a @problem_fact_collection_property or a @planning_entity_collection_property.

  • @problem_fact_collection_property(type) is used to indicate a method returns Problem Facts. The first parameter of the decorator is the type of the Problem Fact Collection (required). It should be a list.

  • @planning_entity_collection_property(type) is used to indicate a method returns Planning Entities. The first parameter of the decorator is the type of the Planning Entity Collection (required). It should be a list.

  • @planning_score(scoreType) is used to tell OptaPlanner what field holds the score. The method MUST begin with get and have a corresponding set method (i.e. get_score(self), set_score(self, score)). The first parameter of the decorator is the score type (required).

Constraints

You define your constraints by using the 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)

Solve

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 will be a TimeTable instance with planning variables set to the final best solution found.

Build

  1. Install the python build module (if not already installed):

    pip install build
  2. In the optapy-core directory, use the command below to build the optapy python wheel into the dist directory:

    cd optapy-core
    python -m build
  3. Install it into a virtual environment using pip:

    # Activate a virtual environment first
    source my_project/venv/bin/activate
    pip install dist/optapy-*-py3-none-any.whl

More information

For quickstarts, visit the optapy quickstart repository. For a full API spec, visit the OptaPy Documentation.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].