PyJobShop¶
- class Model¶
A simple modeling interface for building a scheduling problem step-by-step.
Methods
Adds a job to the model.
Adds a machine to the model.
Adds a renewable resource to the model.
Adds a consumable resource to the model.
Adds a task to the model.
Adds a processing mode to the model.
Adds a constraint that task 1 must start before task 2 starts, with an optional delay.
Adds a constraint that task 1 must start before task 2 ends, with an optional delay.
Adds a constraint that task 1 must end before task 2 starts, with an optional delay.
Adds a constraint that task 1 must end before task 2 ends, with an optional delay.
Adds a constraint that task 2 must start exactly at the start of task 1 plus the delay.
Adds a constraint that task 2 must end exactly at the start of task 1 plus the delay.
Adds a constraint that task 2 must start exactly at the end of task 1 plus the delay.
Adds a constraint that task 2 must end exactly at the end of task 1 plus the delay.
Adds a constraint that two tasks must be scheduled with modes that require identical resources.
Adds a constraint that the two tasks must be scheduled with modes that require different resources.
Adds a constraint that the first task must be scheduled right before the second task, meaning that no task is allowed to be scheduled between, on machines that they are both scheduled on.
Adds a constraint that requires the two machines to schedule its tasks in the same sequence.
Adds a setup time between two tasks on a machine.
Adds a mode dependency between one mode and a list of modes, meaning that if the first mode has been selected, one out of the list of modes must be selected.
Adds a constraint that all tasks from the given list are selected, or none are.
Adds a constraint that at least one task from the given list is selected.
Adds a constraint that exactly one task from the given list is selected.
Sets the objective function in this model.
Returns a summary of the model, which is the string representation of the ProblemData instance created by the model.
Creates a Model instance from a ProblemData instance.
Returns a ProblemData object containing the problem instance.
Solves the problem data instance created by the model.
- property resources : list[Machine | Renewable | Consumable]¶
Returns the list of resources in the model.
- property constraints : Constraints¶
Returns the constraints in this model.
-
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(breaks: list[tuple[int, int]] | None =
None, no_idle: bool =False, *, name: str ='') Machine¶ Adds a machine to the model.
-
add_renewable(capacity: int, breaks: list[tuple[int, int]] | None =
None, *, name: str ='') Renewable¶ Adds a renewable resource to the model.
-
add_consumable(capacity: int, breaks: list[tuple[int, int]] | None =
None, *, name: str ='') Consumable¶ Adds a consumable 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, allow_idle: bool =False, allow_breaks: bool =False, optional: bool =False, *, name: str ='') Task¶ Adds a task to the model.
-
add_mode(task: Task, resources: Machine | Renewable | Consumable | list[Machine | Renewable | Consumable], duration: int, demands: int | list[int] | None =
None, *, name: str ='') 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_start_at_start(task1: Task, task2: Task, delay: int =
0) StartAtStart¶ Adds a constraint that task 2 must start exactly at the start of task 1 plus the delay.
-
add_start_at_end(task1: Task, task2: Task, delay: int =
0) StartAtEnd¶ Adds a constraint that task 2 must end exactly at the start of task 1 plus the delay.
-
add_end_at_start(task1: Task, task2: Task, delay: int =
0) EndAtStart¶ Adds a constraint that task 2 must start exactly at the end of task 1 plus the delay.
-
add_end_at_end(task1: Task, task2: Task, delay: int =
0) EndAtEnd¶ Adds a constraint that task 2 must end exactly at the end of task 1 plus the 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 be scheduled between, on machines that they are both scheduled on.
-
add_same_sequence(machine1: Machine, machine2: Machine, tasks1: list[Task] | None =
None, tasks2: list[Task] | None =None) SameSequence¶ Adds a constraint that requires the two machines to schedule its tasks in the same sequence.
- add_setup_time(machine: Machine, task1: Task, task2: Task, duration: int) SetupTime¶
Adds a setup time between two tasks on a machine.
- add_mode_dependency(mode1: Mode, modes2: list[Mode]) ModeDependency¶
Adds a mode dependency between one mode and a list of modes, meaning that if the first mode has been selected, one out of the list of modes must be selected.
-
add_select_all_or_none(tasks: list[Task], condition_task: Task | None =
None) SelectAllOrNone¶ Adds a constraint that all tasks from the given list are selected, or none are. If
condition_taskis provided, this rule only applies when that task is selected.
-
add_select_at_least_one(tasks: list[Task], condition_task: Task | None =
None) SelectAtLeastOne¶ Adds a constraint that at least one task from the given list is selected. If
condition_taskis provided, this rule only applies when that task is selected.
-
add_select_exactly_one(tasks: list[Task], condition_task: Task | None =
None) SelectExactlyOne¶ Adds a constraint that exactly one task from the given list is selected. If
condition_taskis provided, this rule only applies when that task is selected.
-
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_total_setup_time: int =0) Objective¶ Sets the objective function in this model.
- summary() str¶
Returns a summary of the model, which is the string representation of the ProblemData instance created by the model.
- classmethod from_data(data: ProblemData)¶
Creates a Model instance from a ProblemData instance.
- data() ProblemData¶
Returns a ProblemData object containing the problem instance.
-
solve(solver: 'ortools' | 'cpoptimizer' =
'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: 'ortools' | 'cpoptimizer' =
'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.
- solver: 'ortools' | 'cpoptimizer' =
- Returns:
A Result object containing the best found solution and additional information about the solver run.
- Return type:
-
class ProblemData(jobs: list[Job], resources: list[Machine | Renewable | Consumable], tasks: list[Task], modes: list[Mode], constraints: Constraints =
Constraints(), objective: Objective =Objective(weight_makespan=1))¶ Class that contains all data needed to solve the scheduling problem.
- Parameters:
- jobs: list[Job]¶
List of jobs.
- resources: list[Machine | Renewable | Consumable]¶
List of resources.
- tasks: list[Task]¶
List of tasks.
- modes: list[Mode]¶
List of processing modes of tasks.
- constraints: Constraints =
Constraints()¶ The constraints of this problem data instance.
- objective: Objective =
Objective(weight_makespan=1)¶ The objective function. Default is minimizing the makespan.
- jobs¶
List of jobs.
- resources¶
List of resources.
- tasks¶
List of tasks.
- modes¶
List of processing modes of tasks.
- constraints¶
The constraints of this problem data instance.
- objective¶
The objective function. Default is minimizing the makespan.
-
replace(jobs: list[Job] | None =
None, resources: list[Machine | Renewable | Consumable] | 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: list[Machine | Renewable | Consumable] | 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.
- jobs: list[Job] | None =
- Returns:
A new ProblemData instance with possibly replaced data.
- Return type:
- property renewable_idcs : list[int]¶
Returns the list of resource indices corresponding to renewable resources.
- property consumable_idcs : list[int]¶
Returns the list of resource indices corresponding to consumable resources.
- resource2modes(resource: int) list[int]¶
Returns the list of mode indices corresponding to the given resource.
-
to_json(indent: int | str | None =
2, **kwargs) str¶ Serializes this ProblemData instance to a JSON string.
- Parameters:
- indent: int | str | None =
2¶ If
indentis a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines.Noneis the most compact representation. Default is 2.- **kwargs¶
Additional keyword arguments passed to
json.dumps().
- indent: int | str | None =
- Returns:
JSON representation of this problem data instance.
- Return type:
- classmethod from_json(json_str: str, **kwargs) ProblemData¶
Deserializes a ProblemData instance from a JSON string.
- Parameters:
- json_str: str¶
The JSON string to deserialize.
- **kwargs¶
Additional keyword arguments passed to
json.loads().
- Returns:
The deserialized ProblemData instance.
- Return type:
-
class Job(weight: int =
1, release_date: int =0, deadline: int =4398046511104, due_date: int | None =None, tasks: list[int] =[], *, 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. Must be non-negative.
- release_date: int =
0¶ The earliest time that the job may start. Must be non-negative.
- deadline: int =
4398046511104¶ 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.
- due_date: int | None =
None¶ The latest time that the job should be completed before incurring penalties. Can be negative to represent past due dates. Default is None, meaning there is no due date.
- tasks: list[int] =
[]¶ List of task indices that belong to this job. Default is an empty list.
- name: str =
''¶ Name of the job.
- weight: int =
- Raises:
ValueError – If the release date is greater than the deadline.
- weight¶
The weight of the job, used as multiplicative factor in the objective function. Must be non-negative.
- release_date¶
The earliest time that the job may start. Must be non-negative.
- deadline¶
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.
- due_date¶
The latest time that the job should be completed before incurring penalties. Can be negative to represent past due dates. Default is None, meaning there is no due date.
- tasks¶
List of task indices that belong to this job. Default is an empty list.
- name¶
Name of the job.
-
class Machine(breaks: list[tuple[int, int]] =
[], no_idle: bool =False, *, name: str ='')¶ A resource that processes tasks only one at a time and can enforce sequencing constraints.
- Parameters:
- breaks: list[tuple[int, int]] =
[]¶ List of time intervals during which tasks cannot be processed. Each break is represented as a tuple
(start, end), wherestartmust be non-negative andstartmust be smaller thanend. Default is no breaks.- no_idle: bool =
False¶ Whether the machine must operate continuously without idle time between tasks. When
True, tasks are scheduled back-to-back with no gaps, except for required setup times. WhenFalse(default), the machine can remain idle between tasks. Cannot be combined with breaks.- name: str =
''¶ Name of the machine.
- breaks: list[tuple[int, int]] =
- Raises:
ValueError – When breaks are specified and
no_idle=True.
- breaks¶
List of time intervals during which tasks cannot be processed. Each break is represented as a tuple
(start, end), wherestartmust be non-negative andstartmust be smaller thanend. Default is no breaks.
- no_idle¶
Whether the machine must operate continuously without idle time between tasks. When
True, tasks are scheduled back-to-back with no gaps, except for required setup times. WhenFalse(default), the machine can remain idle between tasks. Cannot be combined with breaks.
- name¶
Name of the machine.
-
class Renewable(capacity: int, breaks: list[tuple[int, int]] =
[], *, name: str ='')¶ A resource that replenishes its capacity after each task completion.
- Parameters:
- capacity: int¶
Capacity of the resource. Must be non-negative.
- breaks: list[tuple[int, int]] =
[]¶ List of time intervals during which tasks cannot be processed. Each break is represented as a tuple
(start, end), wherestartmust be non-negative andstartmust be smaller thanend. Default is no breaks.- name: str =
''¶ Name of the resource.
- capacity¶
Capacity of the resource. Must be non-negative.
- breaks¶
List of time intervals during which tasks cannot be processed. Each break is represented as a tuple
(start, end), wherestartmust be non-negative andstartmust be smaller thanend. Default is no breaks.
- name¶
Name of the resource.
-
class Consumable(capacity: int, breaks: list[tuple[int, int]] =
[], *, name: str ='')¶ A resource with finite capacity that is permanently consumed by tasks. Unlike renewable resources, consumed capacity is never replenished during the scheduling horizon.
- Parameters:
- capacity: int¶
Capacity of the resource. Must be non-negative.
- breaks: list[tuple[int, int]] =
[]¶ List of time intervals during which tasks cannot be processed. Each break is represented as a tuple
(start, end), wherestartmust be non-negative andstartmust be smaller thanend. Default is no breaks.- name: str =
''¶ Name of the resource.
- capacity¶
Capacity of the resource. Must be non-negative.
- breaks¶
List of time intervals during which tasks cannot be processed. Each break is represented as a tuple
(start, end), wherestartmust be non-negative andstartmust be smaller thanend. Default is no breaks.
- name¶
Name of the resource.
-
class Task(job: int | None =
None, earliest_start: int =0, latest_start: int =4398046511104, earliest_end: int =0, latest_end: int =4398046511104, allow_idle: bool =False, allow_breaks: bool =False, optional: bool =False, *, name: str ='')¶ Simple dataclass for storing task-related data.
- Parameters:
- job: int | None =
None¶ The index of the job that this task belongs to,
Noneif the task does not belong to any job.- earliest_start: int =
0¶ Earliest start time of the task.
- latest_start: int =
4398046511104¶ Latest start time of the task.
- earliest_end: int =
0¶ Earliest end time of the task.
- latest_end: int =
4398046511104¶ Latest end time of the task.
- allow_idle: bool =
False¶ Whether the task can remain idle after completing its processing. If
True, the task can continue occupying resources after finishing (e.g., blocking in flow shops).- allow_breaks: bool =
False¶ Whether the task can be interrupted by resource breaks. If
True, the task stops processing during breaks and resumes afterwards.- optional: bool =
False¶ Whether the task is optional.
- name: str =
''¶ Name of the task.
- job: int | None =
- job¶
The index of the job that this task belongs to,
Noneif the task does not belong to any job.
- earliest_start¶
Earliest start time of the task.
- latest_start¶
Latest start time of the task.
- earliest_end¶
Earliest end time of the task.
- latest_end¶
Latest end time of the task.
- allow_idle¶
Whether the task can remain idle after completing its processing. If
True, the task can continue occupying resources after finishing (e.g., blocking in flow shops).
- allow_breaks¶
Whether the task can be interrupted by resource breaks. If
True, the task stops processing during breaks and resumes afterwards.
- optional¶
Whether the task is optional.
- name¶
Name of the task.
-
class Mode(task: int, resources: list[int], duration: int, demands: list[int] =
[], *, name: str ='')¶ Simple dataclass for storing processing mode data.
- Parameters:
- task: int¶
Task index that this mode belongs to.
- resources: list[int]¶
List of unique resources that are required for this mode.
- duration: int¶
Processing duration of this mode. Must be non-negative.
- demands: list[int] =
[]¶ List of demands for each resource for this mode. Demands must be non-negative. By default, the demands are initialized as a list of zeros with the same length as the resources.
- name: str =
''¶ Name of the mode.
- Raises:
ValueError – If the length of resources and demands do not match.
- task¶
Task index that this mode belongs to.
- resources¶
List of unique resources that are required for this mode.
- duration¶
Processing duration of this mode. Must be non-negative.
- demands¶
List of demands for each resource for this mode. Demands must be non-negative. By default, the demands are initialized as a list of zeros with the same length as the resources.
- name¶
Name of the mode.
-
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 StartAtStart(task1: int, task2: int, delay: int =
0)¶ Start task 1 (\(s_1\)) at the start of task 2 (\(s_2\)), with an optional delay \(d\). That is,
\[s_1 + d = s_2.\]
-
class StartAtEnd(task1: int, task2: int, delay: int =
0)¶ Start task 1 (\(s_1\)) at the end of task 2 (\(e_2\)), with an optional delay \(d\). That is,
\[s_1 + d = e_2.\]
-
class EndAtStart(task1: int, task2: int, delay: int =
0)¶ End task 1 (\(e_1\)) at the start of task 2 (\(s_2\)), with an optional delay \(d\). That is,
\[e_1 + d = s_2.\]
-
class EndAtEnd(task1: int, task2: int, delay: int =
0)¶ End task 1 (\(e_1\)) at the end of task 2 (\(e_2\)), with an optional delay \(d\). That is,
\[e_1 + d = 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-waving 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 SameSequence(machine1: int, machine2: int, tasks1: list[int] | None =
None, tasks2: list[int] | None =None)¶ Ensures that two machines process their assigned tasks in the same relative order. Both machines must have the same number of assigned tasks for this constraint to be valid.
When
tasks1andtasks2are not specified, the constraint applies to all tasks assigned to each machine, with ordering determined by their task indices in ascending order. For explicit control over the task sequence, use thetasks1andtasks2parameters.Example
Assume that machine 1 can process tasks [1, 3] and machine 2 can process tasks [2, 4]. The default (by task indices) allows the following valid sequences:
(1→3, 2→4) or (3→1, 4→2)
If passing arguments
tasks1=[1, 3]andtasks2=[4, 2], then the following sequences are valid:(1→3, 4→2) or (3→1, 2→4)
- 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.
When using
Machine.breaks, setup times are allowed to take place during the breaks.
- class ModeDependency(mode1: int, modes2: list[int])¶
Represents a dependency between task modes: if mode 1 is selected, then at least one of the modes in modes2 must also be selected.
Let \(m_1\) be the Boolean variable indicating whether mode 1 is selected. Let \(M_2\) be the set of Boolean variables corresponding to the modes in modes2.
The constraint is then expressed as:
\[m_1 \leq \sum_{m \in M_2} m\]
-
class SelectAllOrNone(tasks: list[int], condition_task: int | None =
None)¶ Enforces that all tasks from the given list are selected, or none are.
If
condition_taskis provided, this rule only applies when that task is selected; otherwise, it has no effect.
-
class SelectAtLeastOne(tasks: list[int], condition_task: int | None =
None)¶ Enforces that at least one task from the given list is selected.
If
condition_taskis provided, this rule only applies when that task is selected; otherwise, it has no effect.
-
class SelectExactlyOne(tasks: list[int], condition_task: int | None =
None)¶ Enforces that exactly one task from the given list is selected.
If
condition_taskis provided, this rule only applies when that task is selected; otherwise, it has no effect.
-
class Constraints(start_before_start: list[StartBeforeStart] =
[], start_before_end: list[StartBeforeEnd] =[], end_before_start: list[EndBeforeStart] =[], end_before_end: list[EndBeforeEnd] =[], start_at_start: list[StartAtStart] =[], start_at_end: list[StartAtEnd] =[], end_at_start: list[EndAtStart] =[], end_at_end: list[EndAtEnd] =[], identical_resources: list[IdenticalResources] =[], different_resources: list[DifferentResources] =[], consecutive: list[Consecutive] =[], same_sequence: list[SameSequence] =[], setup_times: list[SetupTime] =[], mode_dependencies: list[ModeDependency] =[], select_all_or_none: list[SelectAllOrNone] =[], select_at_least_one: list[SelectAtLeastOne] =[], select_exactly_one: list[SelectExactlyOne] =[])¶ Simple container class for storing all constraints.
-
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_total_setup_time: int =0)¶ The objective class represents a weighted sum of objective functions \(f\), calculated as: \(\sum_f \text{weight}_f \cdot \text{value}_f\) with \(\text{weight}_f \ge 0\). The objective functions \(f\) are defined below.
In the following, let \(J\) denote the set of jobs, \(T\) denote the set of tasks, \(C_j\) denote the completion time of job \(j\), and \(C_t\) denote the completion time of task \(t\).
- Makespan (\(C_{\max}\)): The finish time of the latest task.
- \[C_{\max} = \max_{t \in T} C_t\]
- Number of tardy jobs (\(NTJ\)): The weighted sum of all tardy jobs, where a job is tardy when it does not meet its due date \(d_j\).
- \[NTJ = \sum_{j \in J} w_j \mathbb{1}_{\{C_j - d_j > 0\}}\]
where \(\mathbb{1}_{\{x\}}\) is the indicator function.
- Total flow time (\(TFT\)): The weighted sum of the length of stay in the system of each job, from their release date to their completion.
- \[TFT = \sum_{j \in J} w_j ( C_j - r_j )\]
- Total tardiness (\(TT\)): The weighted sum of the tardiness of each job, where the tardiness is the difference between completion time and due date \(d_j\) (0 if completed before due date).
- \[TT = \sum_{j \in J} w_j \max(C_j - d_j, 0)\]
- Total earliness (\(TE\)): The weighted sum of the earliness of each job, where earliness is the difference between due date \(d_j\) and completion time (0 if completed after due date).
- \[TE = \sum_{j \in J} w_j (\max(d_j - C_j, 0))\]
- Maximum tardiness (\(U_{\max}\)): The weighted maximum tardiness of all jobs.
- \[U_{\max} = \max_{j \in J} w_j (\max(C_j - d_j, 0))\]
- Total setup time (\(TST\)): The sum of all sequence-dependent setup times between consecutive tasks on each machine, where \(R\) denotes the set of machines, \(M^R_r\) denotes the set of modes requiring \(r \in R\), \(s_{t_u, t_v, r}\) denotes the setup time between tasks \(t_u\) and \(t_v\) on machine \(r\) and \(b_{ruv}\) is the binary variable indicating whether task \(t_u\) is followed by task \(t_v\) on machine \(r\).
- \[TST = \sum_{r \in R} \sum_{u, v \in M^R_r} s_{t_u, t_v, r} b_{ruv}\]
Note
Use
Job.weightto set a specific job’s weight (\(w_j\)) in the objective function.
- class Solution(data: ProblemData, tasks: list[ScheduledTask])¶
Solution to the scheduling problem.
- Parameters:
- data: ProblemData¶
The problem data instance.
- tasks: list[ScheduledTask]¶
The list of ScheduledTask objects, one for each task in the problem, or an empty list if a dummy solution is to be created.
Note
This class does not validate whether the solution is feasible. When instantiated directly, it assumes that the provided task data represent a feasible solution, or an empty solution if no tasks are provided.
- property tasks : list[ScheduledTask]¶
Returns the list of task data.
- property jobs : list[ScheduledJob]¶
Returns the list of job data.
-
class ScheduledTask(mode: int, resources: list[int], start: int, end: int, idle: int =
0, breaks: int =0, present: bool =True)¶ Stores scheduling data related to a task.
- Parameters:
- mode: int¶
The selected mode.
- resources: list[int]¶
The selected resources.
- start: int¶
The start time.
- end: int¶
The end time.
- idle: int =
0¶ The time that this task is not processing, excluding breaks.
- breaks: int =
0¶ The total time that this task is interrupted by resource breaks.
- present: bool =
True¶ Whether the task is present in the solution.
- mode¶
The selected mode.
- resources¶
The selected resources.
- start¶
The start time.
- end¶
The end time.
- idle¶
The time that this task is not processing, excluding breaks.
- breaks¶
The total time that this task is interrupted by resource breaks.
- present¶
Whether the task is present in the solution.
-
class ScheduledJob(start: int, end: int, release_date: int =
0, due_date: int | None =None, present: bool =True)¶ Stores scheduling data related to a job.
- Parameters:
- start: int¶
The start time of the job.
- end: int¶
The end time of the job.
- release_date: int =
0¶ The release date of the job. Default 0.
- due_date: int | None =
None¶ The due date of the job. Default
None.- present: bool =
True¶ Whether at least one of the job’s tasks is present in the solution. If
False, all job attributes are zero orFalse. DefaultTrue.
- start¶
The start time of the job.
- end¶
The end time of the job.
- release_date¶
The release date of the job. Default 0.
- due_date¶
The due date of the job. Default
None.
- present¶
Whether at least one of the job’s tasks is present in the solution. If
False, all job attributes are zero orFalse. DefaultTrue.
- class Result(objective: float, lower_bound: float, status: SolveStatus, runtime: float, best: Solution)¶
Result class that stores information about the solver run.
- Parameters:
- objective: float¶
The objective value of the solution. If no feasible solution was found, this is set to
float('inf').- lower_bound: float¶
The lower bound of the objective function. If no feasible solution was found, this is set to 0.
- status: SolveStatus¶
The termination status of the solver run.
- runtime: float¶
The runtime of the solver.
- best: Solution¶
The best found solution. If no feasible solution was found, this is an empty solution.
- objective¶
The objective value of the solution. If no feasible solution was found, this is set to
float('inf').
- lower_bound¶
The lower bound of the objective function. If no feasible solution was found, this is set to 0.
- status¶
The termination status of the solver run.
- runtime¶
The runtime of the solver.
- best¶
The best found solution. If no feasible solution was found, this is an empty solution.
- class SolveStatus¶
Enum representing the termination status of the solver run.
-
OPTIMAL =
"Optimal"¶ Solution is proven optimal.
-
FEASIBLE =
"Feasible"¶ A feasible solution was found.
-
INFEASIBLE =
"Infeasible"¶ Problem is proven infeasible.
-
TIME_LIMIT =
"Time-limit"¶ Solver terminated due to time limit.
-
UNKNOWN =
"Unknown"¶ Solver terminated with unknown status.
-
OPTIMAL =
-
solve(data: ProblemData, solver: 'ortools' | 'cpoptimizer' =
'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: 'ortools' | 'cpoptimizer' =
'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:
- Raises:
ModuleNotFoundError – If CP Optimizer is chosen but its dependencies are not installed.