job-shop-lib 0.5.1__py3-none-any.whl → 1.0.0a1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. job_shop_lib/__init__.py +16 -8
  2. job_shop_lib/{base_solver.py → _base_solver.py} +1 -1
  3. job_shop_lib/{job_shop_instance.py → _job_shop_instance.py} +9 -4
  4. job_shop_lib/_operation.py +95 -0
  5. job_shop_lib/{schedule.py → _schedule.py} +73 -54
  6. job_shop_lib/{scheduled_operation.py → _scheduled_operation.py} +13 -37
  7. job_shop_lib/benchmarking/__init__.py +66 -43
  8. job_shop_lib/benchmarking/_load_benchmark.py +88 -0
  9. job_shop_lib/constraint_programming/__init__.py +13 -0
  10. job_shop_lib/{cp_sat/ortools_solver.py → constraint_programming/_ortools_solver.py} +57 -18
  11. job_shop_lib/dispatching/__init__.py +45 -41
  12. job_shop_lib/dispatching/{dispatcher.py → _dispatcher.py} +153 -80
  13. job_shop_lib/dispatching/_dispatcher_observer_config.py +54 -0
  14. job_shop_lib/dispatching/_factories.py +125 -0
  15. job_shop_lib/dispatching/{history_tracker.py → _history_observer.py} +4 -6
  16. job_shop_lib/dispatching/{pruning_functions.py → _ready_operation_filters.py} +6 -35
  17. job_shop_lib/dispatching/_unscheduled_operations_observer.py +69 -0
  18. job_shop_lib/dispatching/feature_observers/__init__.py +16 -10
  19. job_shop_lib/dispatching/feature_observers/{composite_feature_observer.py → _composite_feature_observer.py} +84 -2
  20. job_shop_lib/dispatching/feature_observers/{duration_observer.py → _duration_observer.py} +6 -17
  21. job_shop_lib/dispatching/feature_observers/{earliest_start_time_observer.py → _earliest_start_time_observer.py} +114 -35
  22. job_shop_lib/dispatching/feature_observers/{factory.py → _factory.py} +31 -5
  23. job_shop_lib/dispatching/feature_observers/{feature_observer.py → _feature_observer.py} +59 -16
  24. job_shop_lib/dispatching/feature_observers/_is_completed_observer.py +97 -0
  25. job_shop_lib/dispatching/feature_observers/_is_ready_observer.py +33 -0
  26. job_shop_lib/dispatching/feature_observers/{position_in_job_observer.py → _position_in_job_observer.py} +1 -8
  27. job_shop_lib/dispatching/feature_observers/{remaining_operations_observer.py → _remaining_operations_observer.py} +8 -26
  28. job_shop_lib/dispatching/rules/__init__.py +51 -0
  29. job_shop_lib/dispatching/rules/_dispatching_rule_factory.py +82 -0
  30. job_shop_lib/dispatching/{dispatching_rule_solver.py → rules/_dispatching_rule_solver.py} +44 -15
  31. job_shop_lib/dispatching/{dispatching_rules.py → rules/_dispatching_rules_functions.py} +74 -21
  32. job_shop_lib/dispatching/rules/_machine_chooser_factory.py +69 -0
  33. job_shop_lib/dispatching/rules/_utils.py +127 -0
  34. job_shop_lib/exceptions.py +18 -0
  35. job_shop_lib/generation/__init__.py +2 -2
  36. job_shop_lib/generation/{general_instance_generator.py → _general_instance_generator.py} +26 -7
  37. job_shop_lib/generation/{instance_generator.py → _instance_generator.py} +13 -3
  38. job_shop_lib/graphs/__init__.py +17 -6
  39. job_shop_lib/graphs/{job_shop_graph.py → _job_shop_graph.py} +81 -2
  40. job_shop_lib/graphs/{node.py → _node.py} +18 -12
  41. job_shop_lib/graphs/graph_updaters/__init__.py +13 -0
  42. job_shop_lib/graphs/graph_updaters/_graph_updater.py +59 -0
  43. job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py +154 -0
  44. job_shop_lib/graphs/graph_updaters/_utils.py +25 -0
  45. job_shop_lib/reinforcement_learning/__init__.py +41 -0
  46. job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py +366 -0
  47. job_shop_lib/reinforcement_learning/_reward_observers.py +85 -0
  48. job_shop_lib/reinforcement_learning/_single_job_shop_graph_env.py +337 -0
  49. job_shop_lib/reinforcement_learning/_types_and_constants.py +61 -0
  50. job_shop_lib/reinforcement_learning/_utils.py +96 -0
  51. job_shop_lib/visualization/__init__.py +20 -4
  52. job_shop_lib/visualization/{agent_task_graph.py → _agent_task_graph.py} +28 -9
  53. job_shop_lib/visualization/_gantt_chart_creator.py +219 -0
  54. job_shop_lib/visualization/_gantt_chart_video_and_gif_creation.py +388 -0
  55. {job_shop_lib-0.5.1.dist-info → job_shop_lib-1.0.0a1.dist-info}/METADATA +68 -44
  56. job_shop_lib-1.0.0a1.dist-info/RECORD +66 -0
  57. job_shop_lib/benchmarking/load_benchmark.py +0 -142
  58. job_shop_lib/cp_sat/__init__.py +0 -5
  59. job_shop_lib/dispatching/factories.py +0 -206
  60. job_shop_lib/dispatching/feature_observers/is_completed_observer.py +0 -98
  61. job_shop_lib/dispatching/feature_observers/is_ready_observer.py +0 -40
  62. job_shop_lib/generators/__init__.py +0 -8
  63. job_shop_lib/generators/basic_generator.py +0 -200
  64. job_shop_lib/generators/transformations.py +0 -164
  65. job_shop_lib/operation.py +0 -122
  66. job_shop_lib/visualization/create_gif.py +0 -209
  67. job_shop_lib-0.5.1.dist-info/RECORD +0 -52
  68. /job_shop_lib/dispatching/feature_observers/{is_scheduled_observer.py → _is_scheduled_observer.py} +0 -0
  69. /job_shop_lib/generation/{transformations.py → _transformations.py} +0 -0
  70. /job_shop_lib/graphs/{build_agent_task_graph.py → _build_agent_task_graph.py} +0 -0
  71. /job_shop_lib/graphs/{build_disjunctive_graph.py → _build_disjunctive_graph.py} +0 -0
  72. /job_shop_lib/graphs/{constants.py → _constants.py} +0 -0
  73. /job_shop_lib/visualization/{disjunctive_graph.py → _disjunctive_graph.py} +0 -0
  74. /job_shop_lib/visualization/{gantt_chart.py → _gantt_chart.py} +0 -0
  75. {job_shop_lib-0.5.1.dist-info → job_shop_lib-1.0.0a1.dist-info}/LICENSE +0 -0
  76. {job_shop_lib-0.5.1.dist-info → job_shop_lib-1.0.0a1.dist-info}/WHEEL +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: job-shop-lib
3
- Version: 0.5.1
3
+ Version: 1.0.0a1
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,7 +12,8 @@ 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: imageio (>=2,<3)
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)
@@ -23,9 +24,9 @@ Description-Content-Type: text/markdown
23
24
 
24
25
  <div align="center">
25
26
 
26
- <img src="images/logo_with_transparent_background.png" height="150px">
27
+ <img src="docs/source/images/jslib_minimalist_logo_no_background_fixed.png" height="150px">
27
28
 
28
- <h1>Job Shop Library</h1>
29
+ <h1>JobShopLib</h1>
29
30
 
30
31
  [![Tests](https://github.com/Pabloo22/job_shop_lib/actions/workflows/tests.yaml/badge.svg)](https://github.com/Pabloo22/job_shop_lib/actions/workflows/tests.yaml)
31
32
  ![Python versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)
@@ -34,25 +35,57 @@ Description-Content-Type: text/markdown
34
35
 
35
36
  </div>
36
37
 
37
- An easy-to-use and modular Python library for the Job Shop Scheduling Problem (JSSP) with a special focus on graph representations.
38
+ JobShopLib is a Python package for creating, solving, and visualizing Job Shop Scheduling Problems (JSSP).
38
39
 
39
- It provides intuitive data structures to represent instances and solutions, as well as solvers and visualization tools.
40
+ It follows a modular design, allowing users to easily extend the library with new solvers, dispatching rules, visualization functions, etc.
40
41
 
41
- See the [this](https://colab.research.google.com/drive/1XV_Rvq1F2ns6DFG8uNj66q_rcowwTZ4H?usp=sharing) Google Colab notebook for a quick start guide!
42
+ See [this](https://colab.research.google.com/drive/1XV_Rvq1F2ns6DFG8uNj66q_rcowwTZ4H?usp=sharing) Google Colab notebook for a quick start guide!
42
43
 
43
- ## Installation
44
+ ## Installation :package:
44
45
 
45
- You can install the library from PyPI:
46
+ <!-- start installation -->
47
+
48
+ JobShopLib is distributed on [PyPI](https://pypi.org/project/job-shop-lib/) and it supports Python 3.10+.
49
+
50
+ You can install the latest version using `pip`:
46
51
 
47
52
  ```bash
48
53
  pip install job-shop-lib
49
54
  ```
50
55
 
51
- ## Quick Start :rocket:
56
+ <!-- end installation -->
57
+
58
+ <!-- key features -->
59
+
60
+ ## Key Features :star:
61
+
62
+ - **Data Structures**: Easily create, manage, and manipulate job shop instances and solutions with user-friendly data structures. See [Getting Started](docs/source/examples/00-Getting-Started.ipynb) and [How Solutions are Represented](docs/source/examples/01-How-Solutions-are-Represented.ipynb).
63
+
64
+ - **Benchmark Instances**: Load well-known benchmark instances directly from the library without manual downloading. See [Load Benchmark Instances](docs/source/examples/05-Load-Benchmark-Instances.ipynb).
65
+
66
+ - **Random Instance Generation**: Create random instances with customizable sizes and properties or augment existing ones. See [`generation`](job_shop_lib/generation) package.
67
+
68
+ - **Multiple Solvers**:
69
+ - **Constraint Programming Solver**: OR-Tools' CP-SAT solver. See [Solving the Problem](docs/source/examples/02-Solving-the-Problem.ipynb).
70
+
71
+ - **Dispatching Rule Solvers**: Use any of the available dispatching rules or create custom ones. See [Dispatching Rules](docs/source/examples/03-Dispatching-Rules.ipynb).
72
+
73
+ - **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](docs/source/examples/06-Save-Gif.ipynb).
74
+
75
+ - **Graph Representations**:
76
+ - **Disjunctive Graphs**: Represent and visualize instances as disjunctive graphs. See [Disjunctive Graph](docs/source/examples/04-Disjunctive-Graph.ipynb).
77
+ - **Agent-Task Graphs**: Encode instances as agent-task graphs (introduced in [ScheduleNet paper](https://arxiv.org/abs/2106.03051)). See [Agent-Task Graph](docs/source/examples/07-Agent-Task-Graph.ipynb).
78
+ - Build your own custom graphs with the `JobShopGraph` class.
79
+
80
+ - **Gymnasium Environments**: Two environments for solving the problem with Graph Neural Networks (GNNs) or any other method, and Reinforcement Learning (RL). See [SingleJobShopGraphEnv](docs/source/examples/09-SingleJobShopGraphEnv.ipynb) and [MultiJobShopGraphEnv](examples/10-MultiJobShopGraphEnv.ipynb).
81
+
82
+ <!-- end key features -->
83
+
84
+ ## Some Examples :rocket:
52
85
 
53
86
  ### Create a Job Shop Instance
54
87
 
55
- You can create a Job Shop Instance by defining the jobs and operations. An operation is defined by the machine(s) it is processed on and the duration (processing time).
88
+ 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
89
 
57
90
  ```python
58
91
  from job_shop_lib import JobShopInstance, Operation
@@ -83,7 +116,7 @@ from job_shop_lib.benchmarking import load_benchmark_instance
83
116
  ft06 = load_benchmark_instance("ft06")
84
117
  ```
85
118
 
86
- The module `benchmarks` contains functions to load the instances from the file and return them as `JobShopInstance` objects without having to download them
119
+ The module `benchmarking` contains functions to load the instances from the file and return them as `JobShopInstance` objects without having to download them
87
120
  manually.
88
121
 
89
122
  The contributions to this benchmark dataset are as follows:
@@ -115,12 +148,12 @@ https://github.com/thomasWeise/jsspInstancesAndResults
115
148
 
116
149
  ### Generate a Random Instance
117
150
 
118
- You can also generate a random instance with the `BasicGenerator` class.
151
+ You can also generate a random instance with the `GeneralInstanceGenerator` class.
119
152
 
120
153
  ```python
121
- from job_shop_lib.generators import BasicGenerator
154
+ from job_shop_lib.generation import GeneralInstanceGenerator
122
155
 
123
- generator = BasicGenerator(
156
+ generator = GeneralInstanceGenerator(
124
157
  duration_range=(5, 10), seed=42, num_jobs=5, num_machines=5
125
158
  )
126
159
  random_instance = generator.generate()
@@ -129,7 +162,7 @@ random_instance = generator.generate()
129
162
  This class can also work as an iterator to generate multiple instances:
130
163
 
131
164
  ```python
132
- generator = BasicGenerator(iteration_limit=100, seed=42)
165
+ generator = GeneralInstanceGenerator(iteration_limit=100, seed=42)
133
166
  instances = []
134
167
  for instance in generator:
135
168
  instances.append(instance)
@@ -145,7 +178,7 @@ Every solver is a `Callable` that receives a `JobShopInstance` and returns a `Sc
145
178
  ```python
146
179
  import matplotlib.pyplot as plt
147
180
 
148
- from job_shop_lib.cp_sat import ORToolsSolver
181
+ from job_shop_lib.constraint_programming import ORToolsSolver
149
182
  from job_shop_lib.visualization import plot_gantt_chart
150
183
 
151
184
  solver = ORToolsSolver(max_time_in_seconds=10)
@@ -154,7 +187,7 @@ ft06_schedule = solver(ft06)
154
187
  fig, ax = plot_gantt_chart(ft06_schedule)
155
188
  plt.show()
156
189
  ```
157
- ![Example Gannt Chart](images/ft06_solution.png)
190
+ ![Example Gannt Chart](docs/source/images/ft06_solution.png)
158
191
 
159
192
  ### Solve an Instance with a Dispatching Rule Solver
160
193
 
@@ -190,7 +223,7 @@ create_gif(
190
223
  )
191
224
  ```
192
225
 
193
- ![Example Gif](examples/ft06_optimized.gif)
226
+ ![Example Gif](docs/source/examples/output/ft06_optimized.gif)
194
227
 
195
228
  The dashed red line represents the current time step, which is computed as the earliest time when the next operation can start.
196
229
 
@@ -217,11 +250,11 @@ fig = plot_disjunctive_graph(instance)
217
250
  plt.show()
218
251
  ```
219
252
 
220
- ![Example Disjunctive Graph](images/example_disjunctive_graph.png)
253
+ ![Example Disjunctive Graph](docs/source/images/example_disjunctive_graph.png)
221
254
 
222
255
 
223
- > [!WARNING]
224
- > This plot function requires having the optional dependency [PyGraphViz](https://pygraphviz.github.io/) installed.
256
+ > [!TIP]
257
+ > Installing the optional dependency [PyGraphViz](https://pygraphviz.github.io/) is recommended.
225
258
 
226
259
  The `JobShopGraph` class provides easy access to the nodes, for example, to get all the nodes of a specific type:
227
260
 
@@ -276,7 +309,7 @@ plt.show()
276
309
  ```
277
310
 
278
311
  <div align="center">
279
- <img src="examples/agent_task_graph.png" width="300">
312
+ <img src="docs/source/images/agent_task_graph.png" width="300">
280
313
  </div>
281
314
  <br>
282
315
 
@@ -286,43 +319,34 @@ For more details, check the [examples](examples) folder.
286
319
 
287
320
  ## Installation for development
288
321
 
289
- ### With Poetry
322
+ <!-- start installation development -->
290
323
 
291
324
  1. Clone the repository.
292
325
 
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
326
  ```bash
299
- poetry shell
327
+ git clone https://github.com/Pabloo22/job_shop_lib.git
328
+ cd job_shop_lib
300
329
  ```
301
- 4. Install dependencies:
330
+
331
+ 2. Install [poetry](https://python-poetry.org/docs/) if you don't have it already:
332
+
302
333
  ```bash
303
- poetry install --with notebooks --with test --with lint --all-extras
334
+ pip install poetry
304
335
  ```
305
- or equivalently:
336
+
337
+ 3. Install dependencies:
306
338
  ```bash
307
339
  make poetry_install_all
308
340
  ```
309
341
 
310
- ### With PyPI
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
- ```
342
+ <!-- end installation development -->
319
343
 
320
- ## License
344
+ ## License :scroll:
321
345
 
322
346
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
323
347
 
324
348
 
325
- ## References
349
+ ## References :books:
326
350
 
327
351
  - J. Adams, E. Balas, and D. Zawack, "The shifting bottleneck procedure
328
352
  for job shop scheduling," Management Science, vol. 34, no. 3,
@@ -0,0 +1,66 @@
1
+ job_shop_lib/__init__.py,sha256=Ci5ipn-zciO88C5aX5Wx-UN8iBTbpde3dSSg02ZcfwM,597
2
+ job_shop_lib/_base_solver.py,sha256=p17XmtufNc9Y481cqZUT45pEkUmmW1HWG53dfhIBJH8,1363
3
+ job_shop_lib/_job_shop_instance.py,sha256=Q0ml3C36tmcBskBo8MyaZWILJPbdvHjJcvXzD_YfLsU,16475
4
+ job_shop_lib/_operation.py,sha256=8Wj8ZLpxmHw4lJJbLCZoTpFhLaap9MSzwOA5VOJQ-DY,3099
5
+ job_shop_lib/_schedule.py,sha256=2QjhU21pZr7Gl6qEVJ9kXujx-bSrvaTdyZvjGbrQqzs,11193
6
+ job_shop_lib/_scheduled_operation.py,sha256=w7jKhgJ4dQycJ5wSItAd_B9gH5ipcoqy5KxtHFxWTP0,2775
7
+ job_shop_lib/benchmarking/__init__.py,sha256=BYCrJUNr_uk2c0xIbDt07OnUMhQx8Dudkukx3TFWxgw,3271
8
+ job_shop_lib/benchmarking/_load_benchmark.py,sha256=-cgyx0Kn6uAc3KdGFSQb6eUVQjQggmpVKOH9qusNkXI,2930
9
+ job_shop_lib/benchmarking/benchmark_instances.json,sha256=F9EvyzFwVxiKAN6rQTsrMhsKstmyUmroyWduM7a00KQ,464841
10
+ job_shop_lib/constraint_programming/__init__.py,sha256=kKQRUxxS_nVFUdXGnf4bQOD9mqrXxZZWElS753A4YiA,454
11
+ job_shop_lib/constraint_programming/_ortools_solver.py,sha256=U6kkk2pHsAgKLOhEjl6R1FFLy-i5_5sxBHaXezMR1tI,9860
12
+ job_shop_lib/dispatching/__init__.py,sha256=QV7qy-y0sSoKp_FslTm7sdqczYzpq0YctzKQ36l0ykg,1510
13
+ job_shop_lib/dispatching/_dispatcher.py,sha256=PCSBpYAF6QPXWrjwkBQXTxOdGdq6Y1Uqw8esQTW05TQ,21357
14
+ job_shop_lib/dispatching/_dispatcher_observer_config.py,sha256=l_lbaw9JJ5icVOmDAzAL6G5t6wG25bQLpRedN1bys8c,1932
15
+ job_shop_lib/dispatching/_factories.py,sha256=UAZLq7d_-puzMYteiAbbhkcW5ucKO-lo3bj8pCCEnOA,4229
16
+ job_shop_lib/dispatching/_history_observer.py,sha256=Vl8rQaxekUeEB-AyNxyC3c76zQakeh-rdri2iDnZvXw,610
17
+ job_shop_lib/dispatching/_ready_operation_filters.py,sha256=q8Xv4kp_2GsvEMC5mlTuJXivAz_b8bbrqo5sXaS3PJU,3110
18
+ job_shop_lib/dispatching/_unscheduled_operations_observer.py,sha256=LNEzqOWqEf6fvtkQrDmDWFEhCfA75OgEtzdomzbxYII,2683
19
+ job_shop_lib/dispatching/feature_observers/__init__.py,sha256=oPrhxw65znMhLugMqUD-1swNi8MufejQbHKiMxtgCU0,1103
20
+ job_shop_lib/dispatching/feature_observers/_composite_feature_observer.py,sha256=SqZ7Th97p1SkmHz2O_xdPCoqiPNwEs71n_iSkCO3FQM,6397
21
+ job_shop_lib/dispatching/feature_observers/_duration_observer.py,sha256=RfWXtxXvS4lakIRWPa1tD0I_UGgb7-h4-tTVvA_x4tA,3490
22
+ job_shop_lib/dispatching/feature_observers/_earliest_start_time_observer.py,sha256=iBkfGxG9-peO8shJKTl2P59YFq63aX_Z4XUvOL6m79g,8912
23
+ job_shop_lib/dispatching/feature_observers/_factory.py,sha256=3nlLDzdf_UJqmNO1Om69ygxj-9mF4kfPBp0rFFUC_a0,2773
24
+ job_shop_lib/dispatching/feature_observers/_feature_observer.py,sha256=N-UhOsw3VbasKucuZlAJyF-k0O7CiwtGFez39xOF66Q,5174
25
+ job_shop_lib/dispatching/feature_observers/_is_completed_observer.py,sha256=_ZSmHt1ZtLNXBipaeSOXwgY14WWN3tIm9sx8WY4-zBw,3448
26
+ job_shop_lib/dispatching/feature_observers/_is_ready_observer.py,sha256=iRr2MsCAglb6dO5fhHKSD7Z2ZHRjYqXK7E8bimAfpOY,1244
27
+ job_shop_lib/dispatching/feature_observers/_is_scheduled_observer.py,sha256=PeLxPVLJX_TP4TG8ViEQFR8WS43wIp6CqyuapM8lIt8,1477
28
+ job_shop_lib/dispatching/feature_observers/_position_in_job_observer.py,sha256=hvztjuajYRx-CnmflWqN4lG06pJelZIRZmarjPK9Afo,1107
29
+ job_shop_lib/dispatching/feature_observers/_remaining_operations_observer.py,sha256=kNvRVbxsx5SI2nMc9ZbmcPd5wDaxiljhkXpk6biV2rI,1442
30
+ job_shop_lib/dispatching/rules/__init__.py,sha256=p1rkqf66L62uvAOM1ZxNV8xHoh7SuYjHi_8ZNBvPIjg,1450
31
+ job_shop_lib/dispatching/rules/_dispatching_rule_factory.py,sha256=5fNpv90fAoR6rcE6NeJOWiB7ir-FVnoONIhHtKJ9H0E,2904
32
+ job_shop_lib/dispatching/rules/_dispatching_rule_solver.py,sha256=r-z3AHwbYNRRnrifoz1gmKASpWqxrUQoxvyfara92KM,5331
33
+ job_shop_lib/dispatching/rules/_dispatching_rules_functions.py,sha256=Wb9fQIfePvCJi4RqJ59UrRSnYufgQw5nQ_Am8M6-JOI,7569
34
+ job_shop_lib/dispatching/rules/_machine_chooser_factory.py,sha256=xsJ8nJwPDBi-sfLJRQF_BBQDbyXDfopD1U-efXffQAE,2331
35
+ job_shop_lib/dispatching/rules/_utils.py,sha256=X8vET2p1D3RyoB9mFfsfRgmilcTmxPssKYyJQ2zEt0Q,4605
36
+ job_shop_lib/exceptions.py,sha256=ARzpoZJCvRIvOesCiqqFSRxkv6w9WwEXx0aBP-l2IKA,1597
37
+ job_shop_lib/generation/__init__.py,sha256=hUqjnE0bEoknuUwFoLUWjBH26qTTCGsJAW4gscAbiQ8,294
38
+ job_shop_lib/generation/_general_instance_generator.py,sha256=8DG70qT2TUTyPp-3Q1DHWo3DhtUvyB4Yo_u0eAa5CIc,7431
39
+ job_shop_lib/generation/_instance_generator.py,sha256=fPcbNoyk0t1JtJpBMiwk3SlyPkWYNkYS7-Vs8qH_eDM,4642
40
+ job_shop_lib/generation/_transformations.py,sha256=FI2qHrETATJUrQP3-RYhZAQ5boyEZ0CF2StDbacBej8,5290
41
+ job_shop_lib/graphs/__init__.py,sha256=Kzw__atE5q_bbLf-vDwqya453RP-CfgV7RlURbdOfSc,1646
42
+ job_shop_lib/graphs/_build_agent_task_graph.py,sha256=ktj-oNLUPmWHfL81EVyaoF4hXClWYfnN7oG2Nn4pOsg,7128
43
+ job_shop_lib/graphs/_build_disjunctive_graph.py,sha256=z1jiuTTaWPJZj-vSZdo064quGx4LEDKjtZIb1FieZW4,3705
44
+ job_shop_lib/graphs/_constants.py,sha256=dqPF--okue5sF70Iv-YR14QKFx4pxPwT2dL1Rh5jylM,374
45
+ job_shop_lib/graphs/_job_shop_graph.py,sha256=QmYj-DptmV3Mca0JHplPa1YPt6D4zDSdIwclKK15Ib0,9938
46
+ job_shop_lib/graphs/_node.py,sha256=FcV92cH1RK6xv8qK3d4QaCRzB-C2kY0MtVeWNgsdi6U,5769
47
+ job_shop_lib/graphs/graph_updaters/__init__.py,sha256=utejVUdKNa3g_6HpfTKanv-9K9sVFlRnqhWpRPGxEHU,358
48
+ job_shop_lib/graphs/graph_updaters/_graph_updater.py,sha256=H8PtBj4gv6y5wQKOstF2CSnLsFjO1YeVHpzvYK3vMRM,2053
49
+ job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py,sha256=kPuBmion70-GAQsyFal8gHylHvZSoBJae9eF8iGOkvA,6097
50
+ job_shop_lib/graphs/graph_updaters/_utils.py,sha256=X5YfwJA1CCgpm1r9C036Gal2CkDh2SSak7wl7TbdjHw,704
51
+ job_shop_lib/reinforcement_learning/__init__.py,sha256=QVFo9e1X-tpanZkGdcCPV_WobQ2EZ_y5uoYSJ36XrQI,957
52
+ job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py,sha256=jKMcWYBvz1kwlw00Xe1x9HqhFkMMqlh-Y95NmeBL3-0,15129
53
+ job_shop_lib/reinforcement_learning/_reward_observers.py,sha256=4Kdyn9Jlp_1sBtVr6raF-ZFtcnKxwyCLykfX53TmuhU,2959
54
+ job_shop_lib/reinforcement_learning/_single_job_shop_graph_env.py,sha256=Kbd3N1rKcXm6IHTo99En-oX85vqVobv2bFBCyAht2mE,12949
55
+ job_shop_lib/reinforcement_learning/_types_and_constants.py,sha256=CY849lbv6UXy40KRcMJT3WxvGWrLqcfysu65LPkTfg8,1715
56
+ job_shop_lib/reinforcement_learning/_utils.py,sha256=ilI089Bs8CRlfRV_yH6XH8oypTDtRa7hS-H4iRCC5lU,2497
57
+ job_shop_lib/visualization/__init__.py,sha256=jXC188u5AnSWcO1lRZEzZAPZTXbqlYSPhYc7LMc0itU,1094
58
+ job_shop_lib/visualization/_agent_task_graph.py,sha256=AaBTD_S34WjrsZnL_iMAplR_f67RahZi7x58SOvp-q0,8834
59
+ job_shop_lib/visualization/_disjunctive_graph.py,sha256=pg4KG9BfQbnBPnXYgbyPGe0AuHSmhYqPeqWYAf_spWQ,5905
60
+ job_shop_lib/visualization/_gantt_chart.py,sha256=B9sn4XrEUqgQhRKju-1VUG5R67AZXRu7jbrtA8VcndU,4412
61
+ job_shop_lib/visualization/_gantt_chart_creator.py,sha256=qFhCfk3oC3uF7Mau3lrNhH-34sfHXvkqEXbsDzrIbBk,7721
62
+ job_shop_lib/visualization/_gantt_chart_video_and_gif_creation.py,sha256=XXRLpC05E3zY4SIytdFP2QuxmGA95VohUVmzoFzEt7Q,13206
63
+ job_shop_lib-1.0.0a1.dist-info/LICENSE,sha256=9mggivMGd5taAu3xbmBway-VQZMBzurBGHofFopvUsQ,1069
64
+ job_shop_lib-1.0.0a1.dist-info/METADATA,sha256=h5mdFHRaXbnL7F4lMjGNVE5-TSx35rvAG8SlzX3wWiU,14810
65
+ job_shop_lib-1.0.0a1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
66
+ job_shop_lib-1.0.0a1.dist-info/RECORD,,
@@ -1,142 +0,0 @@
1
- """Module for loading benchmark instances.
2
-
3
- All benchmark instances are stored in a single JSON file. This module provides
4
- functions to load the instances from the file and return them as
5
- JobShopInstance objects.
6
-
7
- The contributions to this benchmark dataset are as follows:
8
-
9
- abz5-9: This subset, comprising five instances, was introduced by Adams et
10
- al. (1988).
11
- ft06, ft10, ft20: These three instances are attributed to the work of
12
- Fisher and Thompson, as detailed in their 1963 work.
13
- la01-40: A collection of forty instances, this group was contributed by
14
- Lawrence, as referenced in his 1984 report.
15
- orb01-10: Ten instances in this category were provided by Applegate and
16
- Cook, as seen in their 1991 study.
17
- swb01-20: This segment, encompassing twenty instances, was contributed by
18
- Storer et al., as per their 1992 article.
19
- yn1-4: Yamada and Nakano are credited with the addition of four instances
20
- in this group, as found in their 1992 paper.
21
- ta01-80: The largest contribution, consisting of eighty instances, was
22
- made by Taillard, as documented in his 1993 paper.
23
-
24
- The metadata from these instances has been updated using data from:
25
-
26
- Thomas Weise. jsspInstancesAndResults. Accessed in January 2024.
27
- Available at: https://github.com/thomasWeise/jsspInstancesAndResults
28
-
29
- It includes the following information:
30
- - "optimum" (int | None): The optimal makespan for the instance.
31
- - "lower_bound" (int): The lower bound for the makespan. If
32
- optimality is known, it is equal to the optimum.
33
- - "upper_bound" (int): The upper bound for the makespan. If
34
- optimality is known, it is equal to the optimum.
35
- - "reference" (str): The paper or source where the instance was first
36
- introduced.
37
-
38
- References:
39
- - J. Adams, E. Balas, and D. Zawack, "The shifting bottleneck procedure
40
- for job shop scheduling," Management Science, vol. 34, no. 3,
41
- pp. 391–401, 1988.
42
-
43
- - J.F. Muth and G.L. Thompson, Industrial scheduling. Englewood Cliffs,
44
- NJ: Prentice-Hall, 1963.
45
-
46
- - S. Lawrence, "Resource constrained project scheduling: An experimental
47
- investigation of heuristic scheduling techniques (Supplement),"
48
- Carnegie-Mellon University, Graduate School of Industrial
49
- Administration, Pittsburgh, Pennsylvania, 1984.
50
-
51
- - D. Applegate and W. Cook, "A computational study of job-shop
52
- scheduling," ORSA Journal on Computer, vol. 3, no. 2, pp. 149–156,
53
- 1991.
54
-
55
- - R.H. Storer, S.D. Wu, and R. Vaccari, "New search spaces for
56
- sequencing problems with applications to job-shop scheduling,"
57
- Management Science, vol. 38, no. 10, pp. 1495–1509, 1992.
58
-
59
- - T. Yamada and R. Nakano, "A genetic algorithm applicable to
60
- large-scale job-shop problems," in Proceedings of the Second
61
- International Workshop on Parallel Problem Solving from Nature
62
- (PPSN'2), Brussels, Belgium, pp. 281–290, 1992.
63
-
64
- - E. Taillard, "Benchmarks for basic scheduling problems," European
65
- Journal of Operational Research, vol. 64, no. 2, pp. 278–285, 1993.
66
- """
67
-
68
- from typing import Any
69
-
70
- import functools
71
- import json
72
- from importlib import resources
73
-
74
- from job_shop_lib import JobShopInstance
75
-
76
-
77
- @functools.cache
78
- def load_all_benchmark_instances() -> dict[str, JobShopInstance]:
79
- """Loads all benchmark instances available.
80
-
81
- Returns:
82
- A dictionary containing the names of the benchmark instances as keys
83
- and the corresponding JobShopInstance objects as values.
84
-
85
- """
86
- benchmark_instances_dict = load_benchmark_json()
87
- return {
88
- name: load_benchmark_instance(name)
89
- for name in benchmark_instances_dict
90
- }
91
-
92
-
93
- def load_benchmark_instance(name: str) -> JobShopInstance:
94
- """Loads a specific benchmark instance.
95
-
96
- Calls to `load_benchmark_json` to load the benchmark instances from the
97
- JSON file. The instance is then loaded from the dictionary using the
98
- provided name. Since `load_benchmark_json` is cached, the file is only
99
- read once.
100
-
101
- Args:
102
- name: The name of the benchmark instance to load. Can be one of the
103
- following: "abz5-9", "ft06", "ft10", "ft20", "la01-40", "orb01-10",
104
- "swb01-20", "yn1-4", or "ta01-80".
105
- """
106
- benchmark_dict = load_benchmark_json()[name]
107
- return JobShopInstance.from_matrices(
108
- duration_matrix=benchmark_dict["duration_matrix"],
109
- machines_matrix=benchmark_dict["machines_matrix"],
110
- name=name,
111
- metadata=benchmark_dict["metadata"],
112
- )
113
-
114
-
115
- @functools.cache
116
- def load_benchmark_json() -> dict[str, dict[str, Any]]:
117
- """Loads the raw JSON file containing the benchmark instances.
118
-
119
- Results are cached to avoid reading the file multiple times.
120
-
121
- Each instance is represented as a dictionary with the following keys
122
- and values:
123
- - "name" (str): The name of the instance.
124
- - "duration_matrix" (list[list[int]]): The matrix containing the
125
- durations for each operation.
126
- - "machines_matrix" (list[list[int]]): The matrix containing the
127
- machines for each operation.
128
- - "metadata" (dict[str, Any]): A dictionary containing metadata
129
- about the instance. The keys are "optimum" (int | None),
130
- "lower_bound" (int), "upper_bound" (int),
131
- and "reference" (str).
132
-
133
- Returns:
134
- The dictionary containing the benchmark instances.
135
- """
136
- benchmark_file = (
137
- resources.files("job_shop_lib.benchmarking")
138
- / "benchmark_instances.json"
139
- )
140
-
141
- with benchmark_file.open("r", encoding="utf-8") as f:
142
- return json.load(f)
@@ -1,5 +0,0 @@
1
- from job_shop_lib.cp_sat.ortools_solver import ORToolsSolver
2
-
3
- __all__ = [
4
- "ORToolsSolver",
5
- ]
@@ -1,206 +0,0 @@
1
- """Contains factory functions for creating dispatching rules, machine choosers,
2
- and pruning functions for the job shop scheduling problem.
3
-
4
- The factory functions create and return the appropriate functions based on the
5
- specified names or enums.
6
- """
7
-
8
- from enum import Enum
9
-
10
- from collections.abc import Callable, Sequence
11
- import random
12
-
13
- from job_shop_lib import Operation
14
- from job_shop_lib.dispatching import (
15
- shortest_processing_time_rule,
16
- first_come_first_served_rule,
17
- most_work_remaining_rule,
18
- most_operations_remaining_rule,
19
- random_operation_rule,
20
- Dispatcher,
21
- prune_dominated_operations,
22
- prune_non_immediate_machines,
23
- create_composite_pruning_function,
24
- )
25
-
26
-
27
- class DispatchingRule(str, Enum):
28
- """Enumeration of dispatching rules for the job shop scheduling problem."""
29
-
30
- SHORTEST_PROCESSING_TIME = "shortest_processing_time"
31
- FIRST_COME_FIRST_SERVED = "first_come_first_served"
32
- MOST_WORK_REMAINING = "most_work_remaining"
33
- MOST_OPERATIONS_REMAINING = "most_operations_remaining"
34
- RANDOM = "random"
35
-
36
-
37
- class MachineChooser(str, Enum):
38
- """Enumeration of machine chooser strategies for the job shop scheduling"""
39
-
40
- FIRST = "first"
41
- RANDOM = "random"
42
-
43
-
44
- class PruningFunction(str, Enum):
45
- """Enumeration of pruning functions.
46
-
47
- A pruning function is used by the `Dispatcher` class to reduce the
48
- amount of available operations to choose from.
49
- """
50
-
51
- DOMINATED_OPERATIONS = "dominated_operations"
52
- NON_IMMEDIATE_MACHINES = "non_immediate_machines"
53
-
54
-
55
- def dispatching_rule_factory(
56
- dispatching_rule: str | DispatchingRule,
57
- ) -> Callable[[Dispatcher], Operation]:
58
- """Creates and returns a dispatching rule function based on the specified
59
- dispatching rule name.
60
-
61
- The dispatching rule function determines the order in which operations are
62
- selected for execution based on certain criteria such as shortest
63
- processing time, first come first served, etc.
64
-
65
- Args:
66
- dispatching_rule: The name of the dispatching rule to be used.
67
- Supported values are 'shortest_processing_time',
68
- 'first_come_first_served', 'most_work_remaining',
69
- and 'random'.
70
-
71
- Returns:
72
- A function that takes a Dispatcher instance as input and returns an
73
- Operation based on the specified dispatching rule.
74
-
75
- Raises:
76
- ValueError: If the dispatching_rule argument is not recognized or is
77
- not supported.
78
- """
79
- dispatching_rules = {
80
- DispatchingRule.SHORTEST_PROCESSING_TIME: (
81
- shortest_processing_time_rule
82
- ),
83
- DispatchingRule.FIRST_COME_FIRST_SERVED: first_come_first_served_rule,
84
- DispatchingRule.MOST_WORK_REMAINING: most_work_remaining_rule,
85
- DispatchingRule.MOST_OPERATIONS_REMAINING: (
86
- most_operations_remaining_rule
87
- ),
88
- DispatchingRule.RANDOM: random_operation_rule,
89
- }
90
-
91
- dispatching_rule = dispatching_rule.lower()
92
- if dispatching_rule not in dispatching_rules:
93
- raise ValueError(
94
- f"Dispatching rule {dispatching_rule} not recognized. Available "
95
- f"dispatching rules: {', '.join(dispatching_rules)}."
96
- )
97
-
98
- return dispatching_rules[dispatching_rule] # type: ignore[index]
99
-
100
-
101
- def machine_chooser_factory(
102
- machine_chooser: str,
103
- ) -> Callable[[Dispatcher, Operation], int]:
104
- """Creates and returns a machine chooser function based on the specified
105
- machine chooser strategy name.
106
-
107
- The machine chooser function determines which machine an operation should
108
- be assigned to for execution. The selection can be based on different
109
- strategies such as choosing the first available machine or selecting a
110
- machine randomly.
111
-
112
- Args:
113
- machine_chooser (str): The name of the machine chooser strategy to be
114
- used. Supported values are 'first' and 'random'.
115
-
116
- Returns:
117
- A function that takes a Dispatcher instance and an Operation as input
118
- and returns the index of the selected machine based on the specified
119
- machine chooser strategy.
120
-
121
- Raises:
122
- ValueError: If the machine_chooser argument is not recognized or is
123
- not supported.
124
- """
125
- machine_choosers: dict[str, Callable[[Dispatcher, Operation], int]] = {
126
- MachineChooser.FIRST: lambda _, operation: operation.machines[0],
127
- MachineChooser.RANDOM: lambda _, operation: random.choice(
128
- operation.machines
129
- ),
130
- }
131
-
132
- machine_chooser = machine_chooser.lower()
133
- if machine_chooser not in machine_choosers:
134
- raise ValueError(
135
- f"Machine chooser {machine_chooser} not recognized. Available "
136
- f"machine choosers: {', '.join(machine_choosers)}."
137
- )
138
-
139
- return machine_choosers[machine_chooser]
140
-
141
-
142
- def composite_pruning_function_factory(
143
- pruning_function_names: Sequence[str | PruningFunction],
144
- ) -> Callable[[Dispatcher, list[Operation]], list[Operation]]:
145
- """Creates and returns a composite pruning function based on the
146
- specified list of pruning strategies.
147
-
148
- The composite pruning function filters out operations based on
149
- the specified list of pruning strategies.
150
-
151
- Args:
152
- pruning_functions:
153
- A list of pruning strategies to be used. Supported values are
154
- 'dominated_operations' and 'non_immediate_machines'.
155
-
156
- Returns:
157
- A function that takes a Dispatcher instance and a list of Operation
158
- instances as input and returns a list of Operation instances based on
159
- the specified list of pruning strategies.
160
-
161
- Raises:
162
- ValueError: If any of the pruning strategies in the list are not
163
- recognized or are not supported.
164
- """
165
-
166
- pruning_functions = [
167
- pruning_function_factory(name) for name in pruning_function_names
168
- ]
169
- return create_composite_pruning_function(pruning_functions)
170
-
171
-
172
- def pruning_function_factory(
173
- pruning_function_name: str | PruningFunction,
174
- ) -> Callable[[Dispatcher, list[Operation]], list[Operation]]:
175
- """Creates and returns a pruning function based on the specified
176
- pruning strategy name.
177
-
178
- The pruning function filters out operations based on certain
179
- criteria such as dominated operations, non-immediate machines, etc.
180
-
181
- Args:
182
- pruning_function:
183
- The name of the pruning function to be used. Supported values are
184
- 'dominated_operations' and 'non_immediate_machines'.
185
-
186
- Returns:
187
- A function that takes a Dispatcher instance and a list of Operation
188
- instances as input and returns a list of Operation instances based on
189
- the specified pruning function.
190
-
191
- Raises:
192
- ValueError: If the pruning_function argument is not recognized or is
193
- not supported.
194
- """
195
- pruning_strategies = {
196
- PruningFunction.DOMINATED_OPERATIONS: prune_dominated_operations,
197
- PruningFunction.NON_IMMEDIATE_MACHINES: prune_non_immediate_machines,
198
- }
199
-
200
- if pruning_function_name not in pruning_strategies:
201
- raise ValueError(
202
- f"Unsupported pruning function '{pruning_function_name}'. "
203
- f"Supported values are {', '.join(pruning_strategies.keys())}."
204
- )
205
-
206
- return pruning_strategies[pruning_function_name] # type: ignore[index]