job-shop-lib 0.5.0__tar.gz → 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {job_shop_lib-0.5.0 → job_shop_lib-1.0.0}/PKG-INFO +87 -55
- {job_shop_lib-0.5.0 → job_shop_lib-1.0.0}/README.md +83 -52
- job_shop_lib-1.0.0/job_shop_lib/__init__.py +32 -0
- job_shop_lib-0.5.0/job_shop_lib/base_solver.py → job_shop_lib-1.0.0/job_shop_lib/_base_solver.py +1 -1
- job_shop_lib-0.5.0/job_shop_lib/job_shop_instance.py → job_shop_lib-1.0.0/job_shop_lib/_job_shop_instance.py +155 -81
- job_shop_lib-1.0.0/job_shop_lib/_operation.py +118 -0
- job_shop_lib-0.5.0/job_shop_lib/schedule.py → job_shop_lib-1.0.0/job_shop_lib/_schedule.py +102 -84
- job_shop_lib-0.5.0/job_shop_lib/scheduled_operation.py → job_shop_lib-1.0.0/job_shop_lib/_scheduled_operation.py +25 -49
- job_shop_lib-1.0.0/job_shop_lib/benchmarking/__init__.py +101 -0
- job_shop_lib-1.0.0/job_shop_lib/benchmarking/_load_benchmark.py +88 -0
- job_shop_lib-1.0.0/job_shop_lib/constraint_programming/__init__.py +13 -0
- job_shop_lib-0.5.0/job_shop_lib/cp_sat/ortools_solver.py → job_shop_lib-1.0.0/job_shop_lib/constraint_programming/_ortools_solver.py +77 -22
- job_shop_lib-1.0.0/job_shop_lib/dispatching/__init__.py +61 -0
- job_shop_lib-0.5.0/job_shop_lib/dispatching/dispatcher.py → job_shop_lib-1.0.0/job_shop_lib/dispatching/_dispatcher.py +223 -130
- job_shop_lib-1.0.0/job_shop_lib/dispatching/_dispatcher_observer_config.py +67 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/_factories.py +135 -0
- job_shop_lib-0.5.0/job_shop_lib/dispatching/history_tracker.py → job_shop_lib-1.0.0/job_shop_lib/dispatching/_history_observer.py +6 -7
- job_shop_lib-1.0.0/job_shop_lib/dispatching/_optimal_operations_observer.py +113 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/_ready_operation_filters.py +168 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/_unscheduled_operations_observer.py +70 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/__init__.py +66 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/_composite_feature_observer.py +212 -0
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/duration_observer.py → job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/_duration_observer.py +20 -18
- job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/_earliest_start_time_observer.py +289 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/_factory.py +95 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/_feature_observer.py +228 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/_is_completed_observer.py +97 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/_is_ready_observer.py +35 -0
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/is_scheduled_observer.py → job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/_is_scheduled_observer.py +9 -5
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/position_in_job_observer.py → job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/_position_in_job_observer.py +8 -10
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/remaining_operations_observer.py → job_shop_lib-1.0.0/job_shop_lib/dispatching/feature_observers/_remaining_operations_observer.py +8 -26
- job_shop_lib-1.0.0/job_shop_lib/dispatching/rules/__init__.py +87 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/rules/_dispatching_rule_factory.py +84 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/rules/_dispatching_rule_solver.py +201 -0
- job_shop_lib-0.5.0/job_shop_lib/dispatching/dispatching_rules.py → job_shop_lib-1.0.0/job_shop_lib/dispatching/rules/_dispatching_rules_functions.py +70 -16
- job_shop_lib-1.0.0/job_shop_lib/dispatching/rules/_machine_chooser_factory.py +71 -0
- job_shop_lib-1.0.0/job_shop_lib/dispatching/rules/_utils.py +128 -0
- {job_shop_lib-0.5.0 → job_shop_lib-1.0.0}/job_shop_lib/exceptions.py +18 -0
- job_shop_lib-1.0.0/job_shop_lib/generation/__init__.py +19 -0
- job_shop_lib-1.0.0/job_shop_lib/generation/_general_instance_generator.py +165 -0
- job_shop_lib-1.0.0/job_shop_lib/generation/_instance_generator.py +133 -0
- job_shop_lib-0.5.0/job_shop_lib/generators/transformations.py → job_shop_lib-1.0.0/job_shop_lib/generation/_transformations.py +16 -12
- job_shop_lib-1.0.0/job_shop_lib/generation/_utils.py +124 -0
- job_shop_lib-1.0.0/job_shop_lib/graphs/__init__.py +70 -0
- job_shop_lib-0.5.0/job_shop_lib/graphs/build_disjunctive_graph.py → job_shop_lib-1.0.0/job_shop_lib/graphs/_build_disjunctive_graph.py +41 -3
- job_shop_lib-0.5.0/job_shop_lib/graphs/build_agent_task_graph.py → job_shop_lib-1.0.0/job_shop_lib/graphs/_build_resource_task_graphs.py +28 -26
- job_shop_lib-1.0.0/job_shop_lib/graphs/_constants.py +38 -0
- job_shop_lib-1.0.0/job_shop_lib/graphs/_job_shop_graph.py +320 -0
- job_shop_lib-1.0.0/job_shop_lib/graphs/_node.py +182 -0
- job_shop_lib-1.0.0/job_shop_lib/graphs/graph_updaters/__init__.py +26 -0
- job_shop_lib-1.0.0/job_shop_lib/graphs/graph_updaters/_disjunctive_graph_updater.py +108 -0
- job_shop_lib-1.0.0/job_shop_lib/graphs/graph_updaters/_graph_updater.py +57 -0
- job_shop_lib-1.0.0/job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py +155 -0
- job_shop_lib-1.0.0/job_shop_lib/graphs/graph_updaters/_utils.py +25 -0
- job_shop_lib-1.0.0/job_shop_lib/py.typed +0 -0
- job_shop_lib-1.0.0/job_shop_lib/reinforcement_learning/__init__.py +68 -0
- job_shop_lib-1.0.0/job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py +398 -0
- job_shop_lib-1.0.0/job_shop_lib/reinforcement_learning/_resource_task_graph_observation.py +329 -0
- job_shop_lib-1.0.0/job_shop_lib/reinforcement_learning/_reward_observers.py +87 -0
- job_shop_lib-1.0.0/job_shop_lib/reinforcement_learning/_single_job_shop_graph_env.py +443 -0
- job_shop_lib-1.0.0/job_shop_lib/reinforcement_learning/_types_and_constants.py +62 -0
- job_shop_lib-1.0.0/job_shop_lib/reinforcement_learning/_utils.py +199 -0
- job_shop_lib-1.0.0/job_shop_lib/visualization/__init__.py +0 -0
- job_shop_lib-1.0.0/job_shop_lib/visualization/gantt/__init__.py +48 -0
- job_shop_lib-1.0.0/job_shop_lib/visualization/gantt/_gantt_chart_creator.py +257 -0
- job_shop_lib-1.0.0/job_shop_lib/visualization/gantt/_gantt_chart_video_and_gif_creation.py +422 -0
- job_shop_lib-0.5.0/job_shop_lib/visualization/gantt_chart.py → job_shop_lib-1.0.0/job_shop_lib/visualization/gantt/_plot_gantt_chart.py +84 -21
- job_shop_lib-1.0.0/job_shop_lib/visualization/graphs/__init__.py +29 -0
- job_shop_lib-1.0.0/job_shop_lib/visualization/graphs/_plot_disjunctive_graph.py +418 -0
- job_shop_lib-1.0.0/job_shop_lib/visualization/graphs/_plot_resource_task_graph.py +389 -0
- {job_shop_lib-0.5.0 → job_shop_lib-1.0.0}/pyproject.toml +33 -5
- job_shop_lib-0.5.0/job_shop_lib/__init__.py +0 -21
- job_shop_lib-0.5.0/job_shop_lib/benchmarking/__init__.py +0 -78
- job_shop_lib-0.5.0/job_shop_lib/benchmarking/load_benchmark.py +0 -142
- job_shop_lib-0.5.0/job_shop_lib/cp_sat/__init__.py +0 -5
- job_shop_lib-0.5.0/job_shop_lib/dispatching/__init__.py +0 -52
- job_shop_lib-0.5.0/job_shop_lib/dispatching/dispatching_rule_solver.py +0 -119
- job_shop_lib-0.5.0/job_shop_lib/dispatching/factories.py +0 -206
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/__init__.py +0 -28
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/composite_feature_observer.py +0 -87
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/earliest_start_time_observer.py +0 -156
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/factory.py +0 -58
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/feature_observer.py +0 -113
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/is_completed_observer.py +0 -98
- job_shop_lib-0.5.0/job_shop_lib/dispatching/feature_observers/is_ready_observer.py +0 -40
- job_shop_lib-0.5.0/job_shop_lib/dispatching/pruning_functions.py +0 -116
- job_shop_lib-0.5.0/job_shop_lib/generators/__init__.py +0 -7
- job_shop_lib-0.5.0/job_shop_lib/generators/basic_generator.py +0 -197
- job_shop_lib-0.5.0/job_shop_lib/graphs/__init__.py +0 -52
- job_shop_lib-0.5.0/job_shop_lib/graphs/constants.py +0 -21
- job_shop_lib-0.5.0/job_shop_lib/graphs/job_shop_graph.py +0 -202
- job_shop_lib-0.5.0/job_shop_lib/graphs/node.py +0 -166
- job_shop_lib-0.5.0/job_shop_lib/operation.py +0 -122
- job_shop_lib-0.5.0/job_shop_lib/visualization/__init__.py +0 -25
- job_shop_lib-0.5.0/job_shop_lib/visualization/agent_task_graph.py +0 -257
- job_shop_lib-0.5.0/job_shop_lib/visualization/create_gif.py +0 -209
- job_shop_lib-0.5.0/job_shop_lib/visualization/disjunctive_graph.py +0 -210
- {job_shop_lib-0.5.0 → job_shop_lib-1.0.0}/LICENSE +0 -0
- {job_shop_lib-0.5.0 → job_shop_lib-1.0.0}/job_shop_lib/benchmarking/benchmark_instances.json +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: job-shop-lib
|
3
|
-
Version: 0.
|
3
|
+
Version: 1.0.0
|
4
4
|
Summary: An easy-to-use and modular Python library for the Job Shop Scheduling Problem (JSSP)
|
5
5
|
License: MIT
|
6
6
|
Author: Pabloo22
|
@@ -12,47 +12,86 @@ Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
14
14
|
Provides-Extra: pygraphviz
|
15
|
-
Requires-Dist:
|
15
|
+
Requires-Dist: gymnasium (>=0.29.1,<0.30.0)
|
16
|
+
Requires-Dist: imageio[ffmpeg] (>=2.34.1,<3.0.0)
|
16
17
|
Requires-Dist: matplotlib (>=3,<4)
|
17
18
|
Requires-Dist: networkx (>=3,<4)
|
18
19
|
Requires-Dist: numpy (>=1.26.4,<2.0.0)
|
19
|
-
Requires-Dist: ortools (>=9.9,<
|
20
|
+
Requires-Dist: ortools (>=9.9,<10.0)
|
20
21
|
Requires-Dist: pyarrow (>=15.0.0,<16.0.0)
|
21
22
|
Requires-Dist: pygraphviz (>=1.12,<2.0) ; extra == "pygraphviz"
|
22
23
|
Description-Content-Type: text/markdown
|
23
24
|
|
24
25
|
<div align="center">
|
25
26
|
|
26
|
-
<img src="images/
|
27
|
+
<img src="docs/source/images/jslib_minimalist_logo_no_background_fixed.png" height="150px">
|
27
28
|
|
28
|
-
<h1>
|
29
|
+
<h1>JobShopLib</h1>
|
29
30
|
|
30
31
|
[](https://github.com/Pabloo22/job_shop_lib/actions/workflows/tests.yaml)
|
32
|
+
[](https://job-shop-lib.readthedocs.io/en/latest/?badge=latest)
|
31
33
|

|
32
34
|
[](https://github.com/psf/black)
|
33
35
|
[](https://opensource.org/licenses/MIT)
|
34
36
|
|
35
37
|
</div>
|
36
38
|
|
37
|
-
|
39
|
+
JobShopLib is a Python package for creating, solving, and visualizing job shop scheduling problems (JSSP).
|
38
40
|
|
39
|
-
It
|
41
|
+
It follows a modular design, allowing users to easily extend the library with new solvers, dispatching rules, visualization functions, etc.
|
40
42
|
|
41
|
-
See the [
|
43
|
+
See the [documentation](https://job-shop-lib.readthedocs.io/en/latest/) for more details about the latest version.
|
42
44
|
|
43
|
-
## Installation
|
45
|
+
## Installation :package:
|
44
46
|
|
45
|
-
|
47
|
+
<!-- start installation -->
|
48
|
+
|
49
|
+
JobShopLib is distributed on [PyPI](https://pypi.org/project/job-shop-lib/) and it supports Python 3.10+.
|
50
|
+
|
51
|
+
You can install the latest stable version (version 0.5.1) using `pip`:
|
46
52
|
|
47
53
|
```bash
|
48
54
|
pip install job-shop-lib
|
49
55
|
```
|
50
56
|
|
51
|
-
|
57
|
+
See [this](https://colab.research.google.com/drive/1XV_Rvq1F2ns6DFG8uNj66q_rcowwTZ4H?usp=sharing) Google Colab notebook for a quick start guide!
|
58
|
+
|
59
|
+
|
60
|
+
There is a [documentation page](https://job-shop-lib.readthedocs.io/en/latest/) for versions 1.0.0a3 and onward. See see the [latest pull requests](https://github.com/Pabloo22/job_shop_lib/pulls?q=is%3Apr+is%3Aclosed) for the latest changes.
|
61
|
+
|
62
|
+
<!-- end installation -->
|
63
|
+
|
64
|
+
<!-- key features -->
|
65
|
+
|
66
|
+
## Key Features :star:
|
67
|
+
|
68
|
+
- **Data Structures**: Easily create, manage, and manipulate job shop instances and solutions with user-friendly data structures. See [Getting Started](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/00-Getting-Started.ipynb) and [How Solutions are Represented](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/01-How-Solutions-are-Represented.ipynb).
|
69
|
+
|
70
|
+
- **Benchmark Instances**: Load well-known benchmark instances directly from the library without manual downloading. See [Load Benchmark Instances](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/05-Load-Benchmark-Instances.ipynb).
|
71
|
+
|
72
|
+
- **Random Instance Generation**: Create random instances with customizable sizes and properties or augment existing ones. See [`generation`](job_shop_lib/generation) package.
|
73
|
+
|
74
|
+
- **Multiple Solvers**:
|
75
|
+
- **Constraint Programming Solver**: OR-Tools' CP-SAT solver. See [Solving the Problem](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/02-Solving-the-Problem.ipynb).
|
76
|
+
|
77
|
+
- **Dispatching Rule Solvers**: Use any of the available dispatching rules or create custom ones. See [Dispatching Rules](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/03-Dispatching-Rules.ipynb).
|
78
|
+
|
79
|
+
- **Gantt Charts**: Visualize final schedules and how are they created iteratively by dispatching rule solvers or sequences of scheduling decisions with GIFs or videos. See [Save Gif](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/06-Save-Gif.ipynb).
|
80
|
+
|
81
|
+
- **Graph Representations**:
|
82
|
+
- **Disjunctive Graphs**: Represent and visualize instances as disjunctive graphs. See [Disjunctive Graph](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/04-Disjunctive-Graph.ipynb).
|
83
|
+
- **Agent-Task Graphs**: Encode instances as agent-task graphs (introduced in [ScheduleNet paper](https://arxiv.org/abs/2106.03051)). See [Agent-Task Graph](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/07-Agent-Task-Graph.ipynb).
|
84
|
+
- Build your own custom graphs with the `JobShopGraph` class.
|
85
|
+
|
86
|
+
- **Gymnasium Environments**: Two environments for solving the problem with graph neural networks (GNNs) or any other method, and reinforcement learning (RL). See [SingleJobShopGraphEnv](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/09-SingleJobShopGraphEnv.ipynb) and [MultiJobShopGraphEnv](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/10-MultiJobShopGraphEnv.ipynb).
|
87
|
+
|
88
|
+
<!-- end key features -->
|
89
|
+
|
90
|
+
## Some Examples :rocket:
|
52
91
|
|
53
92
|
### Create a Job Shop Instance
|
54
93
|
|
55
|
-
You can create a
|
94
|
+
You can create a `JobShopInstance` by defining the jobs and operations. An operation is defined by the machine(s) it is processed on and the duration (processing time).
|
56
95
|
|
57
96
|
```python
|
58
97
|
from job_shop_lib import JobShopInstance, Operation
|
@@ -83,7 +122,7 @@ from job_shop_lib.benchmarking import load_benchmark_instance
|
|
83
122
|
ft06 = load_benchmark_instance("ft06")
|
84
123
|
```
|
85
124
|
|
86
|
-
The module `
|
125
|
+
The module `benchmarking` contains functions to load the instances from the file and return them as `JobShopInstance` objects without having to download them
|
87
126
|
manually.
|
88
127
|
|
89
128
|
The contributions to this benchmark dataset are as follows:
|
@@ -115,12 +154,12 @@ https://github.com/thomasWeise/jsspInstancesAndResults
|
|
115
154
|
|
116
155
|
### Generate a Random Instance
|
117
156
|
|
118
|
-
You can also generate a random instance with the `
|
157
|
+
You can also generate a random instance with the `GeneralInstanceGenerator` class.
|
119
158
|
|
120
159
|
```python
|
121
|
-
from job_shop_lib.
|
160
|
+
from job_shop_lib.generation import GeneralInstanceGenerator
|
122
161
|
|
123
|
-
generator =
|
162
|
+
generator = GeneralInstanceGenerator(
|
124
163
|
duration_range=(5, 10), seed=42, num_jobs=5, num_machines=5
|
125
164
|
)
|
126
165
|
random_instance = generator.generate()
|
@@ -129,7 +168,7 @@ random_instance = generator.generate()
|
|
129
168
|
This class can also work as an iterator to generate multiple instances:
|
130
169
|
|
131
170
|
```python
|
132
|
-
generator =
|
171
|
+
generator = GeneralInstanceGenerator(iteration_limit=100, seed=42)
|
133
172
|
instances = []
|
134
173
|
for instance in generator:
|
135
174
|
instances.append(instance)
|
@@ -145,7 +184,7 @@ Every solver is a `Callable` that receives a `JobShopInstance` and returns a `Sc
|
|
145
184
|
```python
|
146
185
|
import matplotlib.pyplot as plt
|
147
186
|
|
148
|
-
from job_shop_lib.
|
187
|
+
from job_shop_lib.constraint_programming import ORToolsSolver
|
149
188
|
from job_shop_lib.visualization import plot_gantt_chart
|
150
189
|
|
151
190
|
solver = ORToolsSolver(max_time_in_seconds=10)
|
@@ -154,7 +193,7 @@ ft06_schedule = solver(ft06)
|
|
154
193
|
fig, ax = plot_gantt_chart(ft06_schedule)
|
155
194
|
plt.show()
|
156
195
|
```
|
157
|
-

|
196
|
+

|
158
197
|
|
159
198
|
### Solve an Instance with a Dispatching Rule Solver
|
160
199
|
|
@@ -190,7 +229,7 @@ create_gif(
|
|
190
229
|
)
|
191
230
|
```
|
192
231
|
|
193
|
-

|
232
|
+

|
194
233
|
|
195
234
|
The dashed red line represents the current time step, which is computed as the earliest time when the next operation can start.
|
196
235
|
|
@@ -200,7 +239,7 @@ The dashed red line represents the current time step, which is computed as the e
|
|
200
239
|
|
201
240
|
### Representing Instances as Graphs
|
202
241
|
|
203
|
-
One of the main purposes of this library is to provide an easy way to encode instances as graphs. This can be very useful, not only for visualization purposes but also for developing
|
242
|
+
One of the main purposes of this library is to provide an easy way to encode instances as graphs. This can be very useful, not only for visualization purposes but also for developing graph neural network-based algorithms.
|
204
243
|
|
205
244
|
A graph is represented by the `JobShopGraph` class, which internally stores a `networkx.DiGraph` object.
|
206
245
|
|
@@ -208,7 +247,7 @@ A graph is represented by the `JobShopGraph` class, which internally stores a `n
|
|
208
247
|
|
209
248
|
The disjunctive graph is created by first adding nodes representing each operation in the jobs, along with two special nodes: a source $S$ and a sink $T$. Each operation node is linked to the next operation in its job sequence by **conjunctive edges**, forming a path from the source to the sink. These edges represent the order in which operations of a single job must be performed.
|
210
249
|
|
211
|
-
Additionally, the graph includes **disjunctive edges** between operations that use the same machine but belong to different jobs. These edges are bidirectional, indicating that either of the connected operations can be performed first. The disjunctive edges thus represent the scheduling choices available: the order in which operations sharing a machine can be processed. Solving the
|
250
|
+
Additionally, the graph includes **disjunctive edges** between operations that use the same machine but belong to different jobs. These edges are bidirectional, indicating that either of the connected operations can be performed first. The disjunctive edges thus represent the scheduling choices available: the order in which operations sharing a machine can be processed. Solving the job shop scheduling problem involves choosing a direction for each disjunctive edge such that the overall processing time is minimized.
|
212
251
|
|
213
252
|
```python
|
214
253
|
from job_shop_lib.visualization import plot_disjunctive_graph
|
@@ -217,11 +256,11 @@ fig = plot_disjunctive_graph(instance)
|
|
217
256
|
plt.show()
|
218
257
|
```
|
219
258
|
|
220
|
-

|
259
|
+

|
221
260
|
|
222
261
|
|
223
|
-
> [!
|
224
|
-
>
|
262
|
+
> [!TIP]
|
263
|
+
> Installing the optional dependency [PyGraphViz](https://pygraphviz.github.io/) is recommended.
|
225
264
|
|
226
265
|
The `JobShopGraph` class provides easy access to the nodes, for example, to get all the nodes of a specific type:
|
227
266
|
|
@@ -250,9 +289,9 @@ Other attributes include:
|
|
250
289
|
- `nodes_by_machine`: A nested list mapping each machine to its associated operation nodes, aiding in machine-specific analysis.
|
251
290
|
- `nodes_by_job`: Similar to `nodes_by_machine`, but maps jobs to their operation nodes, useful for job-specific traversal.
|
252
291
|
|
253
|
-
####
|
292
|
+
#### Resource-Task Graph
|
254
293
|
|
255
|
-
Introduced in the paper "ScheduleNet: Learn to solve multi-agent scheduling problems with reinforcement learning" by [Park et al. (2021)](https://arxiv.org/abs/2106.03051), the
|
294
|
+
Introduced in the paper "ScheduleNet: Learn to solve multi-agent scheduling problems with reinforcement learning" by [Park et al. (2021)](https://arxiv.org/abs/2106.03051), the resource-task graph (orginally named "agent-task graph") is a graph that represents the scheduling problem as a multi-agent reinforcement learning problem.
|
256
295
|
|
257
296
|
In contrast to the disjunctive graph, instead of connecting operations
|
258
297
|
that share the same resources directly by disjunctive edges, operation
|
@@ -263,66 +302,59 @@ from the same job are connected by non-directed edges too.
|
|
263
302
|
|
264
303
|
```python
|
265
304
|
from job_shop_lib.graphs import (
|
266
|
-
|
267
|
-
|
268
|
-
|
305
|
+
build_complete_resource_task_graph,
|
306
|
+
build_resource_task_graph_with_jobs,
|
307
|
+
build_resource_task_graph,
|
269
308
|
)
|
270
|
-
from job_shop_lib.visualization import
|
309
|
+
from job_shop_lib.visualization import plot_resource_task_graph
|
271
310
|
|
272
|
-
|
311
|
+
complete_resource_task_graph = build_complete_resource_task_graph(instance)
|
273
312
|
|
274
|
-
fig =
|
313
|
+
fig = plot_resource_task_graph(complete_agent_task_graph)
|
275
314
|
plt.show()
|
276
315
|
```
|
277
316
|
|
278
317
|
<div align="center">
|
279
|
-
<img src="examples/agent_task_graph.png" width="300">
|
318
|
+
<img src="docs/source/examples/output/agent_task_graph.png" width="300">
|
280
319
|
</div>
|
281
320
|
<br>
|
282
321
|
|
283
322
|
----
|
284
323
|
|
324
|
+
The library generalizes this graph by allowing the addition of job nodes and a global one (see `build_resource_task_graph_with_jobs` and `build_resource_task_graph`).
|
325
|
+
|
285
326
|
For more details, check the [examples](examples) folder.
|
286
327
|
|
287
328
|
## Installation for development
|
288
329
|
|
289
|
-
|
330
|
+
<!-- start installation development -->
|
290
331
|
|
291
332
|
1. Clone the repository.
|
292
333
|
|
293
|
-
2. Install [poetry](https://python-poetry.org/docs/) if you don't have it already:
|
294
|
-
```bash
|
295
|
-
pip install poetry==1.7
|
296
|
-
```
|
297
|
-
3. Create the virtual environment:
|
298
334
|
```bash
|
299
|
-
|
335
|
+
git clone https://github.com/Pabloo22/job_shop_lib.git
|
336
|
+
cd job_shop_lib
|
300
337
|
```
|
301
|
-
|
338
|
+
|
339
|
+
2. Install [poetry](https://python-poetry.org/docs/) if you don't have it already:
|
340
|
+
|
302
341
|
```bash
|
303
|
-
|
342
|
+
pip install poetry
|
304
343
|
```
|
305
|
-
|
344
|
+
|
345
|
+
3. Install dependencies:
|
306
346
|
```bash
|
307
347
|
make poetry_install_all
|
308
348
|
```
|
309
349
|
|
310
|
-
|
311
|
-
|
312
|
-
If you don't want to use Poetry, you can install the library directly from the source code:
|
313
|
-
|
314
|
-
```bash
|
315
|
-
git clone https://github.com/Pabloo22/job_shop_lib.git
|
316
|
-
cd job_shop_lib
|
317
|
-
pip install -e .
|
318
|
-
```
|
350
|
+
<!-- end installation development -->
|
319
351
|
|
320
|
-
## License
|
352
|
+
## License :scroll:
|
321
353
|
|
322
354
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
323
355
|
|
324
356
|
|
325
|
-
## References
|
357
|
+
## References :books:
|
326
358
|
|
327
359
|
- J. Adams, E. Balas, and D. Zawack, "The shifting bottleneck procedure
|
328
360
|
for job shop scheduling," Management Science, vol. 34, no. 3,
|
@@ -1,35 +1,73 @@
|
|
1
1
|
<div align="center">
|
2
2
|
|
3
|
-
<img src="images/
|
3
|
+
<img src="docs/source/images/jslib_minimalist_logo_no_background_fixed.png" height="150px">
|
4
4
|
|
5
|
-
<h1>
|
5
|
+
<h1>JobShopLib</h1>
|
6
6
|
|
7
7
|
[](https://github.com/Pabloo22/job_shop_lib/actions/workflows/tests.yaml)
|
8
|
+
[](https://job-shop-lib.readthedocs.io/en/latest/?badge=latest)
|
8
9
|

|
9
10
|
[](https://github.com/psf/black)
|
10
11
|
[](https://opensource.org/licenses/MIT)
|
11
12
|
|
12
13
|
</div>
|
13
14
|
|
14
|
-
|
15
|
+
JobShopLib is a Python package for creating, solving, and visualizing job shop scheduling problems (JSSP).
|
15
16
|
|
16
|
-
It
|
17
|
+
It follows a modular design, allowing users to easily extend the library with new solvers, dispatching rules, visualization functions, etc.
|
17
18
|
|
18
|
-
See the [
|
19
|
+
See the [documentation](https://job-shop-lib.readthedocs.io/en/latest/) for more details about the latest version.
|
19
20
|
|
20
|
-
## Installation
|
21
|
+
## Installation :package:
|
21
22
|
|
22
|
-
|
23
|
+
<!-- start installation -->
|
24
|
+
|
25
|
+
JobShopLib is distributed on [PyPI](https://pypi.org/project/job-shop-lib/) and it supports Python 3.10+.
|
26
|
+
|
27
|
+
You can install the latest stable version (version 0.5.1) using `pip`:
|
23
28
|
|
24
29
|
```bash
|
25
30
|
pip install job-shop-lib
|
26
31
|
```
|
27
32
|
|
28
|
-
|
33
|
+
See [this](https://colab.research.google.com/drive/1XV_Rvq1F2ns6DFG8uNj66q_rcowwTZ4H?usp=sharing) Google Colab notebook for a quick start guide!
|
34
|
+
|
35
|
+
|
36
|
+
There is a [documentation page](https://job-shop-lib.readthedocs.io/en/latest/) for versions 1.0.0a3 and onward. See see the [latest pull requests](https://github.com/Pabloo22/job_shop_lib/pulls?q=is%3Apr+is%3Aclosed) for the latest changes.
|
37
|
+
|
38
|
+
<!-- end installation -->
|
39
|
+
|
40
|
+
<!-- key features -->
|
41
|
+
|
42
|
+
## Key Features :star:
|
43
|
+
|
44
|
+
- **Data Structures**: Easily create, manage, and manipulate job shop instances and solutions with user-friendly data structures. See [Getting Started](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/00-Getting-Started.ipynb) and [How Solutions are Represented](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/01-How-Solutions-are-Represented.ipynb).
|
45
|
+
|
46
|
+
- **Benchmark Instances**: Load well-known benchmark instances directly from the library without manual downloading. See [Load Benchmark Instances](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/05-Load-Benchmark-Instances.ipynb).
|
47
|
+
|
48
|
+
- **Random Instance Generation**: Create random instances with customizable sizes and properties or augment existing ones. See [`generation`](job_shop_lib/generation) package.
|
49
|
+
|
50
|
+
- **Multiple Solvers**:
|
51
|
+
- **Constraint Programming Solver**: OR-Tools' CP-SAT solver. See [Solving the Problem](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/02-Solving-the-Problem.ipynb).
|
52
|
+
|
53
|
+
- **Dispatching Rule Solvers**: Use any of the available dispatching rules or create custom ones. See [Dispatching Rules](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/03-Dispatching-Rules.ipynb).
|
54
|
+
|
55
|
+
- **Gantt Charts**: Visualize final schedules and how are they created iteratively by dispatching rule solvers or sequences of scheduling decisions with GIFs or videos. See [Save Gif](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/06-Save-Gif.ipynb).
|
56
|
+
|
57
|
+
- **Graph Representations**:
|
58
|
+
- **Disjunctive Graphs**: Represent and visualize instances as disjunctive graphs. See [Disjunctive Graph](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/04-Disjunctive-Graph.ipynb).
|
59
|
+
- **Agent-Task Graphs**: Encode instances as agent-task graphs (introduced in [ScheduleNet paper](https://arxiv.org/abs/2106.03051)). See [Agent-Task Graph](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/07-Agent-Task-Graph.ipynb).
|
60
|
+
- Build your own custom graphs with the `JobShopGraph` class.
|
61
|
+
|
62
|
+
- **Gymnasium Environments**: Two environments for solving the problem with graph neural networks (GNNs) or any other method, and reinforcement learning (RL). See [SingleJobShopGraphEnv](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/09-SingleJobShopGraphEnv.ipynb) and [MultiJobShopGraphEnv](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/10-MultiJobShopGraphEnv.ipynb).
|
63
|
+
|
64
|
+
<!-- end key features -->
|
65
|
+
|
66
|
+
## Some Examples :rocket:
|
29
67
|
|
30
68
|
### Create a Job Shop Instance
|
31
69
|
|
32
|
-
You can create a
|
70
|
+
You can create a `JobShopInstance` by defining the jobs and operations. An operation is defined by the machine(s) it is processed on and the duration (processing time).
|
33
71
|
|
34
72
|
```python
|
35
73
|
from job_shop_lib import JobShopInstance, Operation
|
@@ -60,7 +98,7 @@ from job_shop_lib.benchmarking import load_benchmark_instance
|
|
60
98
|
ft06 = load_benchmark_instance("ft06")
|
61
99
|
```
|
62
100
|
|
63
|
-
The module `
|
101
|
+
The module `benchmarking` contains functions to load the instances from the file and return them as `JobShopInstance` objects without having to download them
|
64
102
|
manually.
|
65
103
|
|
66
104
|
The contributions to this benchmark dataset are as follows:
|
@@ -92,12 +130,12 @@ https://github.com/thomasWeise/jsspInstancesAndResults
|
|
92
130
|
|
93
131
|
### Generate a Random Instance
|
94
132
|
|
95
|
-
You can also generate a random instance with the `
|
133
|
+
You can also generate a random instance with the `GeneralInstanceGenerator` class.
|
96
134
|
|
97
135
|
```python
|
98
|
-
from job_shop_lib.
|
136
|
+
from job_shop_lib.generation import GeneralInstanceGenerator
|
99
137
|
|
100
|
-
generator =
|
138
|
+
generator = GeneralInstanceGenerator(
|
101
139
|
duration_range=(5, 10), seed=42, num_jobs=5, num_machines=5
|
102
140
|
)
|
103
141
|
random_instance = generator.generate()
|
@@ -106,7 +144,7 @@ random_instance = generator.generate()
|
|
106
144
|
This class can also work as an iterator to generate multiple instances:
|
107
145
|
|
108
146
|
```python
|
109
|
-
generator =
|
147
|
+
generator = GeneralInstanceGenerator(iteration_limit=100, seed=42)
|
110
148
|
instances = []
|
111
149
|
for instance in generator:
|
112
150
|
instances.append(instance)
|
@@ -122,7 +160,7 @@ Every solver is a `Callable` that receives a `JobShopInstance` and returns a `Sc
|
|
122
160
|
```python
|
123
161
|
import matplotlib.pyplot as plt
|
124
162
|
|
125
|
-
from job_shop_lib.
|
163
|
+
from job_shop_lib.constraint_programming import ORToolsSolver
|
126
164
|
from job_shop_lib.visualization import plot_gantt_chart
|
127
165
|
|
128
166
|
solver = ORToolsSolver(max_time_in_seconds=10)
|
@@ -131,7 +169,7 @@ ft06_schedule = solver(ft06)
|
|
131
169
|
fig, ax = plot_gantt_chart(ft06_schedule)
|
132
170
|
plt.show()
|
133
171
|
```
|
134
|
-

|
172
|
+

|
135
173
|
|
136
174
|
### Solve an Instance with a Dispatching Rule Solver
|
137
175
|
|
@@ -167,7 +205,7 @@ create_gif(
|
|
167
205
|
)
|
168
206
|
```
|
169
207
|
|
170
|
-

|
208
|
+

|
171
209
|
|
172
210
|
The dashed red line represents the current time step, which is computed as the earliest time when the next operation can start.
|
173
211
|
|
@@ -177,7 +215,7 @@ The dashed red line represents the current time step, which is computed as the e
|
|
177
215
|
|
178
216
|
### Representing Instances as Graphs
|
179
217
|
|
180
|
-
One of the main purposes of this library is to provide an easy way to encode instances as graphs. This can be very useful, not only for visualization purposes but also for developing
|
218
|
+
One of the main purposes of this library is to provide an easy way to encode instances as graphs. This can be very useful, not only for visualization purposes but also for developing graph neural network-based algorithms.
|
181
219
|
|
182
220
|
A graph is represented by the `JobShopGraph` class, which internally stores a `networkx.DiGraph` object.
|
183
221
|
|
@@ -185,7 +223,7 @@ A graph is represented by the `JobShopGraph` class, which internally stores a `n
|
|
185
223
|
|
186
224
|
The disjunctive graph is created by first adding nodes representing each operation in the jobs, along with two special nodes: a source $S$ and a sink $T$. Each operation node is linked to the next operation in its job sequence by **conjunctive edges**, forming a path from the source to the sink. These edges represent the order in which operations of a single job must be performed.
|
187
225
|
|
188
|
-
Additionally, the graph includes **disjunctive edges** between operations that use the same machine but belong to different jobs. These edges are bidirectional, indicating that either of the connected operations can be performed first. The disjunctive edges thus represent the scheduling choices available: the order in which operations sharing a machine can be processed. Solving the
|
226
|
+
Additionally, the graph includes **disjunctive edges** between operations that use the same machine but belong to different jobs. These edges are bidirectional, indicating that either of the connected operations can be performed first. The disjunctive edges thus represent the scheduling choices available: the order in which operations sharing a machine can be processed. Solving the job shop scheduling problem involves choosing a direction for each disjunctive edge such that the overall processing time is minimized.
|
189
227
|
|
190
228
|
```python
|
191
229
|
from job_shop_lib.visualization import plot_disjunctive_graph
|
@@ -194,11 +232,11 @@ fig = plot_disjunctive_graph(instance)
|
|
194
232
|
plt.show()
|
195
233
|
```
|
196
234
|
|
197
|
-

|
235
|
+

|
198
236
|
|
199
237
|
|
200
|
-
> [!
|
201
|
-
>
|
238
|
+
> [!TIP]
|
239
|
+
> Installing the optional dependency [PyGraphViz](https://pygraphviz.github.io/) is recommended.
|
202
240
|
|
203
241
|
The `JobShopGraph` class provides easy access to the nodes, for example, to get all the nodes of a specific type:
|
204
242
|
|
@@ -227,9 +265,9 @@ Other attributes include:
|
|
227
265
|
- `nodes_by_machine`: A nested list mapping each machine to its associated operation nodes, aiding in machine-specific analysis.
|
228
266
|
- `nodes_by_job`: Similar to `nodes_by_machine`, but maps jobs to their operation nodes, useful for job-specific traversal.
|
229
267
|
|
230
|
-
####
|
268
|
+
#### Resource-Task Graph
|
231
269
|
|
232
|
-
Introduced in the paper "ScheduleNet: Learn to solve multi-agent scheduling problems with reinforcement learning" by [Park et al. (2021)](https://arxiv.org/abs/2106.03051), the
|
270
|
+
Introduced in the paper "ScheduleNet: Learn to solve multi-agent scheduling problems with reinforcement learning" by [Park et al. (2021)](https://arxiv.org/abs/2106.03051), the resource-task graph (orginally named "agent-task graph") is a graph that represents the scheduling problem as a multi-agent reinforcement learning problem.
|
233
271
|
|
234
272
|
In contrast to the disjunctive graph, instead of connecting operations
|
235
273
|
that share the same resources directly by disjunctive edges, operation
|
@@ -240,66 +278,59 @@ from the same job are connected by non-directed edges too.
|
|
240
278
|
|
241
279
|
```python
|
242
280
|
from job_shop_lib.graphs import (
|
243
|
-
|
244
|
-
|
245
|
-
|
281
|
+
build_complete_resource_task_graph,
|
282
|
+
build_resource_task_graph_with_jobs,
|
283
|
+
build_resource_task_graph,
|
246
284
|
)
|
247
|
-
from job_shop_lib.visualization import
|
285
|
+
from job_shop_lib.visualization import plot_resource_task_graph
|
248
286
|
|
249
|
-
|
287
|
+
complete_resource_task_graph = build_complete_resource_task_graph(instance)
|
250
288
|
|
251
|
-
fig =
|
289
|
+
fig = plot_resource_task_graph(complete_agent_task_graph)
|
252
290
|
plt.show()
|
253
291
|
```
|
254
292
|
|
255
293
|
<div align="center">
|
256
|
-
<img src="examples/agent_task_graph.png" width="300">
|
294
|
+
<img src="docs/source/examples/output/agent_task_graph.png" width="300">
|
257
295
|
</div>
|
258
296
|
<br>
|
259
297
|
|
260
298
|
----
|
261
299
|
|
300
|
+
The library generalizes this graph by allowing the addition of job nodes and a global one (see `build_resource_task_graph_with_jobs` and `build_resource_task_graph`).
|
301
|
+
|
262
302
|
For more details, check the [examples](examples) folder.
|
263
303
|
|
264
304
|
## Installation for development
|
265
305
|
|
266
|
-
|
306
|
+
<!-- start installation development -->
|
267
307
|
|
268
308
|
1. Clone the repository.
|
269
309
|
|
270
|
-
2. Install [poetry](https://python-poetry.org/docs/) if you don't have it already:
|
271
|
-
```bash
|
272
|
-
pip install poetry==1.7
|
273
|
-
```
|
274
|
-
3. Create the virtual environment:
|
275
310
|
```bash
|
276
|
-
|
311
|
+
git clone https://github.com/Pabloo22/job_shop_lib.git
|
312
|
+
cd job_shop_lib
|
277
313
|
```
|
278
|
-
|
314
|
+
|
315
|
+
2. Install [poetry](https://python-poetry.org/docs/) if you don't have it already:
|
316
|
+
|
279
317
|
```bash
|
280
|
-
|
318
|
+
pip install poetry
|
281
319
|
```
|
282
|
-
|
320
|
+
|
321
|
+
3. Install dependencies:
|
283
322
|
```bash
|
284
323
|
make poetry_install_all
|
285
324
|
```
|
286
325
|
|
287
|
-
|
288
|
-
|
289
|
-
If you don't want to use Poetry, you can install the library directly from the source code:
|
290
|
-
|
291
|
-
```bash
|
292
|
-
git clone https://github.com/Pabloo22/job_shop_lib.git
|
293
|
-
cd job_shop_lib
|
294
|
-
pip install -e .
|
295
|
-
```
|
326
|
+
<!-- end installation development -->
|
296
327
|
|
297
|
-
## License
|
328
|
+
## License :scroll:
|
298
329
|
|
299
330
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
300
331
|
|
301
332
|
|
302
|
-
## References
|
333
|
+
## References :books:
|
303
334
|
|
304
335
|
- J. Adams, E. Balas, and D. Zawack, "The shifting bottleneck procedure
|
305
336
|
for job shop scheduling," Management Science, vol. 34, no. 3,
|
@@ -0,0 +1,32 @@
|
|
1
|
+
"""Contains the main data structures and base classes.
|
2
|
+
|
3
|
+
.. autosummary::
|
4
|
+
:nosignatures:
|
5
|
+
|
6
|
+
Operation
|
7
|
+
JobShopInstance
|
8
|
+
ScheduledOperation
|
9
|
+
Schedule
|
10
|
+
Solver
|
11
|
+
BaseSolver
|
12
|
+
|
13
|
+
"""
|
14
|
+
|
15
|
+
from job_shop_lib._operation import Operation
|
16
|
+
from job_shop_lib._job_shop_instance import JobShopInstance
|
17
|
+
from job_shop_lib._scheduled_operation import ScheduledOperation
|
18
|
+
from job_shop_lib._schedule import Schedule
|
19
|
+
from job_shop_lib._base_solver import BaseSolver, Solver
|
20
|
+
|
21
|
+
|
22
|
+
__version__ = "1.0.0"
|
23
|
+
|
24
|
+
__all__ = [
|
25
|
+
"Operation",
|
26
|
+
"JobShopInstance",
|
27
|
+
"ScheduledOperation",
|
28
|
+
"Schedule",
|
29
|
+
"Solver",
|
30
|
+
"BaseSolver",
|
31
|
+
"__version__",
|
32
|
+
]
|
job_shop_lib-0.5.0/job_shop_lib/base_solver.py → job_shop_lib-1.0.0/job_shop_lib/_base_solver.py
RENAMED
@@ -33,5 +33,5 @@ class BaseSolver(abc.ABC):
|
|
33
33
|
schedule = self.solve(instance)
|
34
34
|
elapsed_time = time_start - time.perf_counter()
|
35
35
|
schedule.metadata["elapsed_time"] = elapsed_time
|
36
|
-
schedule.metadata["solved_by"] =
|
36
|
+
schedule.metadata["solved_by"] = self.__class__.__name__
|
37
37
|
return schedule
|