PyJobShop

class Model

A simple interface for building a scheduling problem step-by-step.

Attributes

constraints

Returns the constraints in this model.

jobs

Returns the list of jobs in the model.

modes

Returns the list of modes in the model.

objective

Returns the objective function in this model.

resources

Returns the list of resources in the model.

tasks

Returns the list of tasks in the model.

Methods

add_consecutive(task1, task2)

Adds a constraint that the first task must be scheduled right before the second task, meaning that no task is allowed to schedule between, on machines that they are both scheduled on.

add_different_resources(task1, task2)

Adds a constraint that the two tasks must be scheduled with modes that require different resources.

add_end_before_end(task1, task2[, delay])

Adds a constraint that task 1 must end before task 2 ends, with an optional delay.

add_end_before_start(task1, task2[, delay])

Adds a constraint that task 1 must end before task 2 starts, with an optional delay.

add_identical_resources(task1, task2)

Adds a constraint that two tasks must be scheduled with modes that require identical resources.

add_job([weight, release_date, deadline, ...])

Adds a job to the model.

add_machine([name])

Adds a machine to the model.

add_mode(task, resources, duration[, demands])

Adds a processing mode to the model.

add_non_renewable(capacity[, name])

Adds a non-renewable resource to the model.

add_renewable(capacity[, name])

Adds a renewable resource to the model.

add_setup_time(machine, task1, task2, duration)

Adds a setup time between two tasks on a machine.

add_start_before_end(task1, task2[, delay])

Adds a constraint that task 1 must start before task 2 ends, with an optional delay.

add_start_before_start(task1, task2[, delay])

Adds a constraint that task 1 must start before task 2 starts, with an optional delay.

add_task([job, earliest_start, ...])

Adds a task to the model.

data()

Returns a ProblemData object containing the problem instance.

from_data(data)

Creates a Model instance from a ProblemData instance.

set_objective([weight_makespan, ...])

Sets the objective function in this model.

solve([solver, time_limit, display, ...])

Solves the problem data instance created by the model.

property jobs : list[Job]

Returns the list of jobs in the model.

property resources : list[Machine | Renewable | NonRenewable]

Returns the list of resources in the model.

property tasks : list[Task]

Returns the list of tasks in the model.

property modes : list[Mode]

Returns the list of modes in the model.

property constraints : Constraints

Returns the constraints in this model.

property objective : Objective

Returns the objective function in this model.

classmethod from_data(data: ProblemData)

Creates a Model instance from a ProblemData instance.

data() ProblemData

Returns a ProblemData object containing the problem instance.

add_job(weight: int = 1, release_date: int = 0, deadline: int = MAX_VALUE, due_date: int | None = None, name: str = '') Job

Adds a job to the model.

add_machine(name: str = '') Machine

Adds a machine to the model.

add_renewable(capacity: int, name: str = '') Renewable

Adds a renewable resource to the model.

add_non_renewable(capacity: int, name: str = '') NonRenewable

Adds a non-renewable resource to the model.

add_task(job: Job | None = None, earliest_start: int = 0, latest_start: int = MAX_VALUE, earliest_end: int = 0, latest_end: int = MAX_VALUE, fixed_duration: bool = True, name: str = '') Task

Adds a task to the model.

add_mode(task: Task, resources: Machine | Renewable | NonRenewable | Sequence[Machine | Renewable | NonRenewable], duration: int, demands: int | list[int] | None = None) Mode

Adds a processing mode to the model.

add_start_before_start(task1: Task, task2: Task, delay: int = 0) StartBeforeStart

Adds a constraint that task 1 must start before task 2 starts, with an optional delay.

add_start_before_end(task1: Task, task2: Task, delay: int = 0) StartBeforeEnd

Adds a constraint that task 1 must start before task 2 ends, with an optional delay.

add_end_before_start(task1: Task, task2: Task, delay: int = 0) EndBeforeStart

Adds a constraint that task 1 must end before task 2 starts, with an optional delay.

add_end_before_end(task1: Task, task2: Task, delay: int = 0) EndBeforeEnd

Adds a constraint that task 1 must end before task 2 ends, with an optional delay.

add_identical_resources(task1: Task, task2: Task) IdenticalResources

Adds a constraint that two tasks must be scheduled with modes that require identical resources.

add_different_resources(task1: Task, task2: Task) DifferentResources

Adds a constraint that the two tasks must be scheduled with modes that require different resources.

add_consecutive(task1: Task, task2: Task) Consecutive

Adds a constraint that the first task must be scheduled right before the second task, meaning that no task is allowed to schedule between, on machines that they are both scheduled on.

add_setup_time(machine: Machine, task1: Task, task2: Task, duration: int) SetupTime

Adds a setup time between two tasks on a machine.

set_objective(weight_makespan: int = 0, weight_tardy_jobs: int = 0, weight_total_tardiness: int = 0, weight_total_flow_time: int = 0, weight_total_earliness: int = 0, weight_max_tardiness: int = 0, weight_max_lateness: int = 0) Objective

Sets the objective function in this model.

solve(solver: str = 'ortools', time_limit: float = float('inf'), display: bool = True, num_workers: int | None = None, initial_solution: Solution | None = None, **kwargs) Result

Solves the problem data instance created by the model.

Parameters:
solver: str = 'ortools'

The solver to use. Either 'ortools' (default) or 'cpoptimizer'.

time_limit: float = float('inf')

The time limit for the solver in seconds. Default float('inf').

display: bool = True

Whether to display the solver output. Default True.

num_workers: int | None = None

The number of workers to use for parallel solving. If not specified, the default of the selected solver is used, which is typically the number of available CPU cores.

initial_solution: Solution | None = None

An initial solution to start the solver from. Default is no solution.

**kwargs

Additional parameters passed to the solver.

Returns:

A Result object containing the best found solution and additional information about the solver run.

Return type:

Result

class ProblemData(jobs: list[Job], resources: Sequence[Machine | Renewable | NonRenewable], tasks: list[Task], modes: list[Mode], constraints: Constraints | None = None, objective: Objective | None = None)

Class that contains all data needed to solve the scheduling problem.

Parameters:
jobs: list[Job]

List of jobs.

resources: Sequence[Machine | Renewable | NonRenewable]

List of resources.

tasks: list[Task]

List of tasks.

modes: list[Mode]

List of processing modes of tasks.

constraints: Constraints | None = None

The constraints of this problem data instance. Default is no constraints.

objective: Objective | None = None

The objective function. Default is minimizing the makespan.

Attributes

constraints

Returns the constraints of this problem instance.

jobs

Returns the job data of this problem instance.

modes

Returns the processing modes of this problem instance.

num_constraints

Returns the number of constraints in this instance.

num_jobs

Returns the number of jobs in this instance.

num_modes

Returns the number of modes in this instance.

num_resources

Returns the number of resources in this instance.

num_tasks

Returns the number of tasks in this instance.

objective

Returns the objective function of this problem instance.

resources

Returns the resource data of this problem instance.

tasks

Returns the task data of this problem instance.

Methods

replace([jobs, resources, tasks, modes, ...])

Returns a new ProblemData instance with possibly replaced data.

replace(jobs: list[Job] | None = None, resources: Sequence[Machine | Renewable | NonRenewable] | None = None, tasks: list[Task] | None = None, modes: list[Mode] | None = None, constraints: Constraints | None = None, objective: Objective | None = None) ProblemData

Returns a new ProblemData instance with possibly replaced data. If a parameter is not provided, the original data is deepcopied instead.

Parameters:
jobs: list[Job] | None = None

Optional list of jobs.

resources: Sequence[Machine | Renewable | NonRenewable] | None = None

Optional list of resources.

tasks: list[Task] | None = None

Optional list of tasks.

modes: list[Mode] | None = None

Optional processing modes of tasks.

constraints: Constraints | None = None

Optional constraints.

objective: Objective | None = None

Optional objective function.

Returns:

A new ProblemData instance with possibly replaced data.

Return type:

ProblemData

property jobs : list[Job]

Returns the job data of this problem instance.

property resources : Sequence[Machine | Renewable | NonRenewable]

Returns the resource data of this problem instance.

property tasks : list[Task]

Returns the task data of this problem instance.

property modes : list[Mode]

Returns the processing modes of this problem instance.

property constraints : Constraints

Returns the constraints of this problem instance.

property objective : Objective

Returns the objective function of this problem instance.

property num_jobs : int

Returns the number of jobs in this instance.

property num_resources : int

Returns the number of resources in this instance.

property num_tasks : int

Returns the number of tasks in this instance.

property num_modes : int

Returns the number of modes in this instance.

property num_constraints : int

Returns the number of constraints in this instance.

class Job(weight: int = 1, release_date: int = 0, deadline: int = MAX_VALUE, due_date: int | None = None, tasks: list[int] | None = None, name: str = '')

Simple dataclass for storing job related data.

Parameters:
weight: int = 1

The weight of the job, used as multiplicative factor in the objective function. Default 1.

release_date: int = 0

The earliest time that the job may start. Default 0.

deadline: int = MAX_VALUE

The latest time by which the job must be completed. Note that a deadline is different from a due date; the latter does not restrict the latest completion time. Default MAX_VALUE.

due_date: int | None = None

The latest time that the job should be completed before incurring penalties. Default None, meaning that there is no due date.

tasks: list[int] | None = None

List of task indices that belong to this job. Default None, which initializes an empty list.

name: str = ''

Name of the job.

Attributes

deadline

The latest time by which the job must be completed.

due_date

The latest time that the job should be completed before incurring penalties.

name

Name of the job.

release_date

The earliest time that the job may start.

tasks

List of task indices that belong to this job.

weight

The weight of the job, used as multiplicative factor in the objective function.

Methods

add_task(idx)

Adds a task index to the job.

property weight : int

The weight of the job, used as multiplicative factor in the objective function.

property release_date : int

The earliest time that the job may start.

property deadline : int

The latest time by which the job must be completed.

property due_date : int | None

The latest time that the job should be completed before incurring penalties.

property tasks : list[int]

List of task indices that belong to this job.

property name : str

Name of the job.

add_task(idx: int)

Adds a task index to the job.

Parameters:
idx: int

Task index to add.

class Machine(name: str = '')

A machine resource is a specialized resource that only processes one task at a time and can handle sequencing constraints.

Parameters:
name: str = ''

Name of the machine.

Attributes

name

Name of the machine.

property name : str

Name of the machine.

class Renewable(capacity: int, name: str = '')

A renewable resource that replenishes its capacity after each task completion.

Parameters:
capacity: int

Capacity of the resource.

name: str = ''

Name of the resource.

Attributes

capacity

Capacity of the resource.

name

Name of the resource.

property capacity : int

Capacity of the resource.

property name : str

Name of the resource.

class NonRenewable(capacity: int, name: str = '')

A non-renewable resource that does not replenish its capacity.

Parameters:
capacity: int

Capacity of the resource.

name: str = ''

Name of the resource.

Attributes

capacity

Capacity of the resource.

name

Name of the resource.

property capacity : int

Capacity of the resource.

property name : str

Name of the resource.

class Task(job: int | None = None, earliest_start: int = 0, latest_start: int = MAX_VALUE, earliest_end: int = 0, latest_end: int = MAX_VALUE, fixed_duration: bool = True, name: str = '')

Simple dataclass for storing task related data.

Parameters:
job: int | None = None

The index of the job that this task belongs to. None if the task does not belong to any job. Default None.

earliest_start: int = 0

Earliest start time of the task. Default 0.

latest_start: int = MAX_VALUE

Latest start time of the task. Default MAX_VALUE.

earliest_end: int = 0

Earliest end time of the task. Default 0.

latest_end: int = MAX_VALUE

Latest end time of the task. Default MAX_VALUE.

fixed_duration: bool = True

Whether the task has a fixed duration. A fixed duration means that the task duration is precisely the processing time (on a given resource). If the duration is not fixed, then the task duration can take longer than the processing time, e.g., due to blocking. Default True.

name: str = ''

Name of the task.

Attributes

earliest_end

Earliest end time of the task.

earliest_start

Earliest start time of the task.

fixed_duration

Whether the task has a fixed duration.

job

The index of the job that this task belongs to.

latest_end

Latest end time of the task.

latest_start

Latest start time of the task.

name

Name of the task.

property job : int | None

The index of the job that this task belongs to. None if the task does not belong to any job.

property earliest_start : int

Earliest start time of the task.

property latest_start : int

Latest start time of the task.

property earliest_end : int

Earliest end time of the task.

property latest_end : int

Latest end time of the task.

property fixed_duration : bool

Whether the task has a fixed duration.

property name : str

Name of the task.

class Mode(task: int, resources: list[int], duration: int, demands: list[int] | None = None)

Simple dataclass for storing processing mode data.

Parameters:
task: int

Task index that this mode belongs to.

resources: list[int]

List of resources that are required for this mode.

duration: int

Processing duration of this mode.

demands: list[int] | None = None

Optional list of demands for each resource for this mode. If None is given, then the demands are initialized as list of zeros with the same length as the resources.

Attributes

demands

duration

resources

task

class Constraints(start_before_start: list[StartBeforeStart] | None = None, start_before_end: list[StartBeforeEnd] | None = None, end_before_start: list[EndBeforeStart] | None = None, end_before_end: list[EndBeforeEnd] | None = None, identical_resources: list[IdenticalResources] | None = None, different_resources: list[DifferentResources] | None = None, consecutive: list[Consecutive] | None = None, setup_times: list[SetupTime] | None = None)

Container class for storing all constraints.

Attributes

consecutive

Returns the list of consecutive task constraints.

different_resources

Returns the list of different resources constraints.

end_before_end

Returns the list of end-before-end constraints.

end_before_start

Returns the list of end-before-start constraints.

identical_resources

Returns the list of identical resources constraints.

setup_times

Returns the list of setup times constraints.

start_before_end

Returns the list of start-before-end constraints.

start_before_start

Returns the list of start-before-start constraints.

property start_before_start : list[StartBeforeStart]

Returns the list of start-before-start constraints.

property start_before_end : list[StartBeforeEnd]

Returns the list of start-before-end constraints.

property end_before_start : list[EndBeforeStart]

Returns the list of end-before-start constraints.

property end_before_end : list[EndBeforeEnd]

Returns the list of end-before-end constraints.

property identical_resources : list[IdenticalResources]

Returns the list of identical resources constraints.

property different_resources : list[DifferentResources]

Returns the list of different resources constraints.

property consecutive : list[Consecutive]

Returns the list of consecutive task constraints.

property setup_times : list[SetupTime]

Returns the list of setup times constraints.

class StartBeforeStart(task1: int, task2: int, delay: int = 0)

Start task 1 (\(s_1\)) before task 2 starts (\(s_2\)), with an optional delay \(d\). That is,

\[s_1 + d \leq s_2.\]
class StartBeforeEnd(task1: int, task2: int, delay: int = 0)

Start task 1 (\(s_1\)) before task 2 ends (\(e_2\)), with an optional delay \(d\). That is,

\[s_1 + d \leq e_2.\]
class EndBeforeStart(task1: int, task2: int, delay: int = 0)

End task 1 (\(e_1\)) before task 2 starts (\(s_2\)), with an optional delay \(d\). That is,

\[e_1 + d \leq s_2.\]
class EndBeforeEnd(task1: int, task2: int, delay: int = 0)

End task 1 (\(e_1\)) before task 2 ends (\(e_2\)), with an optional delay \(d\). That is,

\[e_1 + d \leq e_2.\]
class IdenticalResources(task1: int, task2: int)

Select modes for task 1 and task 2 that use the same resources.

Let \(m_1, m_2\) be the selected modes of task 1 and task 2, and let \(R_m\) denote the resources required by mode \(m\). This constraint ensures that

\[R_{m_1} = R_{m_2}.\]
class DifferentResources(task1: int, task2: int)

Select modes for task 1 and task 2 that use different resources.

Let \(m_1, m_2\) be the selected modes of task 1 and task 2, and let \(R_m\) denote the resources required by mode \(m\). This constraint ensures that

\[R_{m_1} \cap R_{m_2} = \emptyset.\]
class Consecutive(task1: int, task2: int)

Sequence task 1 and task 2 consecutively on the machines they are both assigned to, meaning that no other task is allowed to be scheduled between them.

Hand-waiving some details, let \(m_1, m_2\) be the selected modes of task 1 and task 2, and let \(R\) denote the machines that both modes require. This constraint ensures that

\[m_1 \to m_2 \quad \forall r \in R,\]

where \(\to\) means that \(m_1\) is directly followed by \(m_2\) and no other interval is scheduled between them.

class SetupTime(machine: int, task1: int, task2: int, duration: int)

Sequence-dependent setup time between task 1 and task 2 on the given machine.

Let \(e_1\) be the end time of task 1 and let \(s_2\) be the start time of task 2. If the selected modes of task 1 and task 2 both require the given machine, then this constraint ensures that

\[e_1 + d \leq s_2,\]

where \(d\) is the setup time duration. Note that this also implies an end-before-start relationship between task 1 and task 2.

class Objective(weight_makespan: int = 0, weight_tardy_jobs: int = 0, weight_total_flow_time: int = 0, weight_total_tardiness: int = 0, weight_total_earliness: int = 0, weight_max_tardiness: int = 0, weight_max_lateness: int = 0)

Represents a weighted sum of the following objective functions:

  • Makespan

  • Number of tardy jobs

  • Total flow time

  • Total tardiness

  • Total earliness

  • Maximum tardiness

  • Maximum lateness

Note

Use Job.weight to set a specific job’s weight in the objective function.

class Solution(tasks: list[TaskData])

Solution to the problem.

Parameters:
tasks: list[TaskData]

The list of scheduled tasks.

Attributes

makespan

Returns the makespan of the solution.

tasks

Returns the list of tasks and its scheduling data.

class TaskData(mode: int, resources: list[int], start: int, end: int)

Stores scheduling data related to a task.

Parameters:
mode :

The selected mode.

resources : []

The selected resources.

start :

The start time.

end :

The end time.

class Result(objective: float, lower_bound: float, status: SolveStatus, runtime: float, best: Solution)

Result class that stores information about the solver run.

Parameters:
objective :

The objective value of the solution. If no solution was found, this should be set to float('inf').

lower_bound :

The lower bound of the objective function.

status :

The termination status of the solver run.

runtime :

The runtime of the solver.

best :

The best found solution. If no solution was found, this should be a dummy solution.

class SolveStatus(value)

An enumeration.

solve(data: ProblemData, solver: str = 'ortools', time_limit: float = float('inf'), display: bool = False, num_workers: int | None = None, initial_solution: Solution | None = None, **kwargs) Result

Solves the given problem data instance.

Parameters:
data: ProblemData

The problem data instance.

solver: str = 'ortools'

The solver to use. Either 'ortools' (default) or 'cpoptimizer'.

time_limit: float = float('inf')

The time limit for the solver in seconds. Default float('inf').

display: bool = False

Whether to display the solver output. Default False.

num_workers: int | None = None

The number of workers to use for parallel solving. If not specified, the default of the selected solver is used, which is typically the number of available CPU cores.

initial_solution: Solution | None = None

An initial solution to start the solver from. Default is no solution.

**kwargs

Additional parameters passed to the solver.

Returns:

A Result object containing the best found solution and additional information about the solver run.

Return type:

Result

Raises:

ModuleNotFoundError – If CP Optimizer is chosen but its dependencies are not installed.

MAX_VALUE = 281474976710656

Maximum allowed value, equal to 2^48.

Type:

int