job-shop-lib 1.0.0a5__py3-none-any.whl → 1.0.0b1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. job_shop_lib/__init__.py +1 -1
  2. job_shop_lib/_job_shop_instance.py +34 -29
  3. job_shop_lib/_operation.py +4 -2
  4. job_shop_lib/_schedule.py +11 -11
  5. job_shop_lib/benchmarking/_load_benchmark.py +3 -3
  6. job_shop_lib/constraint_programming/_ortools_solver.py +6 -6
  7. job_shop_lib/dispatching/_dispatcher.py +19 -19
  8. job_shop_lib/dispatching/_dispatcher_observer_config.py +4 -4
  9. job_shop_lib/dispatching/_factories.py +4 -2
  10. job_shop_lib/dispatching/_history_observer.py +2 -1
  11. job_shop_lib/dispatching/_ready_operation_filters.py +19 -18
  12. job_shop_lib/dispatching/_unscheduled_operations_observer.py +4 -3
  13. job_shop_lib/dispatching/feature_observers/_composite_feature_observer.py +7 -8
  14. job_shop_lib/dispatching/feature_observers/_earliest_start_time_observer.py +3 -1
  15. job_shop_lib/dispatching/feature_observers/_factory.py +13 -14
  16. job_shop_lib/dispatching/feature_observers/_feature_observer.py +9 -8
  17. job_shop_lib/dispatching/feature_observers/_is_completed_observer.py +2 -1
  18. job_shop_lib/dispatching/feature_observers/_is_ready_observer.py +4 -2
  19. job_shop_lib/dispatching/rules/_dispatching_rule_factory.py +4 -2
  20. job_shop_lib/dispatching/rules/_dispatching_rule_solver.py +23 -15
  21. job_shop_lib/dispatching/rules/_dispatching_rules_functions.py +9 -8
  22. job_shop_lib/dispatching/rules/_machine_chooser_factory.py +4 -3
  23. job_shop_lib/dispatching/rules/_utils.py +9 -8
  24. job_shop_lib/generation/__init__.py +8 -0
  25. job_shop_lib/generation/_general_instance_generator.py +42 -64
  26. job_shop_lib/generation/_instance_generator.py +11 -7
  27. job_shop_lib/generation/_transformations.py +5 -4
  28. job_shop_lib/generation/_utils.py +124 -0
  29. job_shop_lib/graphs/__init__.py +7 -7
  30. job_shop_lib/graphs/{_build_agent_task_graph.py → _build_resource_task_graphs.py} +26 -24
  31. job_shop_lib/graphs/_job_shop_graph.py +17 -13
  32. job_shop_lib/graphs/_node.py +6 -4
  33. job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py +4 -2
  34. job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py +40 -20
  35. job_shop_lib/reinforcement_learning/_reward_observers.py +3 -1
  36. job_shop_lib/reinforcement_learning/_single_job_shop_graph_env.py +89 -22
  37. job_shop_lib/reinforcement_learning/_types_and_constants.py +1 -1
  38. job_shop_lib/reinforcement_learning/_utils.py +3 -3
  39. job_shop_lib/visualization/__init__.py +0 -60
  40. job_shop_lib/visualization/gantt/__init__.py +48 -0
  41. job_shop_lib/visualization/{_gantt_chart_creator.py → gantt/_gantt_chart_creator.py} +12 -12
  42. job_shop_lib/visualization/{_gantt_chart_video_and_gif_creation.py → gantt/_gantt_chart_video_and_gif_creation.py} +22 -22
  43. job_shop_lib/visualization/{_plot_gantt_chart.py → gantt/_plot_gantt_chart.py} +12 -13
  44. job_shop_lib/visualization/graphs/__init__.py +29 -0
  45. job_shop_lib/visualization/{_plot_disjunctive_graph.py → graphs/_plot_disjunctive_graph.py} +18 -16
  46. job_shop_lib/visualization/graphs/_plot_resource_task_graph.py +389 -0
  47. {job_shop_lib-1.0.0a5.dist-info → job_shop_lib-1.0.0b1.dist-info}/METADATA +17 -15
  48. job_shop_lib-1.0.0b1.dist-info/RECORD +69 -0
  49. job_shop_lib/visualization/_plot_agent_task_graph.py +0 -276
  50. job_shop_lib-1.0.0a5.dist-info/RECORD +0 -66
  51. {job_shop_lib-1.0.0a5.dist-info → job_shop_lib-1.0.0b1.dist-info}/LICENSE +0 -0
  52. {job_shop_lib-1.0.0a5.dist-info → job_shop_lib-1.0.0b1.dist-info}/WHEEL +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: job-shop-lib
3
- Version: 1.0.0a5
3
+ Version: 1.0.0b1
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
@@ -36,7 +36,7 @@ Description-Content-Type: text/markdown
36
36
 
37
37
  </div>
38
38
 
39
- JobShopLib is a Python package for creating, solving, and visualizing Job Shop Scheduling Problems (JSSP).
39
+ JobShopLib is a Python package for creating, solving, and visualizing job shop scheduling problems (JSSP).
40
40
 
41
41
  It follows a modular design, allowing users to easily extend the library with new solvers, dispatching rules, visualization functions, etc.
42
42
 
@@ -60,7 +60,7 @@ See [this](https://colab.research.google.com/drive/1XV_Rvq1F2ns6DFG8uNj66q_rcoww
60
60
  Version 1.0.0 is currently in alpha stage and can be installed with:
61
61
 
62
62
  ```bash
63
- pip install job-shop-lib==1.0.0a5
63
+ pip install job-shop-lib==1.0.0b1
64
64
  ```
65
65
 
66
66
  Although this version is not stable and may contain breaking changes in subsequent releases, it is recommended to install it to access the new reinforcement learning environments and familiarize yourself with new changes (see the [latest pull requests](https://github.com/Pabloo22/job_shop_lib/pulls?q=is%3Apr+is%3Aclosed)). There is a [documentation page](https://job-shop-lib.readthedocs.io/en/latest/) for versions 1.0.0a3 and onward.
@@ -89,7 +89,7 @@ Although this version is not stable and may contain breaking changes in subseque
89
89
  - **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).
90
90
  - Build your own custom graphs with the `JobShopGraph` class.
91
91
 
92
- - **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).
92
+ - **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).
93
93
 
94
94
  <!-- end key features -->
95
95
 
@@ -245,7 +245,7 @@ The dashed red line represents the current time step, which is computed as the e
245
245
 
246
246
  ### Representing Instances as Graphs
247
247
 
248
- 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.
248
+ 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.
249
249
 
250
250
  A graph is represented by the `JobShopGraph` class, which internally stores a `networkx.DiGraph` object.
251
251
 
@@ -253,7 +253,7 @@ A graph is represented by the `JobShopGraph` class, which internally stores a `n
253
253
 
254
254
  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.
255
255
 
256
- 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.
256
+ 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.
257
257
 
258
258
  ```python
259
259
  from job_shop_lib.visualization import plot_disjunctive_graph
@@ -295,9 +295,9 @@ Other attributes include:
295
295
  - `nodes_by_machine`: A nested list mapping each machine to its associated operation nodes, aiding in machine-specific analysis.
296
296
  - `nodes_by_job`: Similar to `nodes_by_machine`, but maps jobs to their operation nodes, useful for job-specific traversal.
297
297
 
298
- #### Agent-Task Graph
298
+ #### Resource-Task Graph
299
299
 
300
- 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 Agent-Task Graph is a graph that represents the scheduling problem as a multi-agent reinforcement learning problem.
300
+ 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.
301
301
 
302
302
  In contrast to the disjunctive graph, instead of connecting operations
303
303
  that share the same resources directly by disjunctive edges, operation
@@ -308,25 +308,27 @@ from the same job are connected by non-directed edges too.
308
308
 
309
309
  ```python
310
310
  from job_shop_lib.graphs import (
311
- build_complete_agent_task_graph,
312
- build_agent_task_graph_with_jobs,
313
- build_agent_task_graph,
311
+ build_complete_resource_task_graph,
312
+ build_resource_task_graph_with_jobs,
313
+ build_resource_task_graph,
314
314
  )
315
- from job_shop_lib.visualization import plot_agent_task_graph
315
+ from job_shop_lib.visualization import plot_resource_task_graph
316
316
 
317
- complete_agent_task_graph = build_complete_agent_task_graph(instance)
317
+ complete_resource_task_graph = build_complete_resource_task_graph(instance)
318
318
 
319
- fig = plot_agent_task_graph(complete_agent_task_graph)
319
+ fig = plot_resource_task_graph(complete_agent_task_graph)
320
320
  plt.show()
321
321
  ```
322
322
 
323
323
  <div align="center">
324
- <img src="docs/source/images/agent_task_graph.png" width="300">
324
+ <img src="docs/source/examples/output/agent_task_graph.png" width="300">
325
325
  </div>
326
326
  <br>
327
327
 
328
328
  ----
329
329
 
330
+ 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`).
331
+
330
332
  For more details, check the [examples](examples) folder.
331
333
 
332
334
  ## Installation for development
@@ -0,0 +1,69 @@
1
+ job_shop_lib/__init__.py,sha256=Mmft9aghnnkZhxx6ZlwsvTx5PjSziJeWgNeDrMoftSY,643
2
+ job_shop_lib/_base_solver.py,sha256=p17XmtufNc9Y481cqZUT45pEkUmmW1HWG53dfhIBJH8,1363
3
+ job_shop_lib/_job_shop_instance.py,sha256=hNQGSJj0rEQpS-YhzwWmM6QzCWp6r--89jkghSgLvUs,18380
4
+ job_shop_lib/_operation.py,sha256=hx2atpP8LPj9fvxpZIfhBFr9Uq6JP-MKAX5JzTvFXso,3847
5
+ job_shop_lib/_schedule.py,sha256=-RdCtTTj-SdNLFucmSVnrCbjZLcBZ4yfhRBdATjAaW8,11292
6
+ job_shop_lib/_scheduled_operation.py,sha256=krjGn47VwsC7bXUTqlUq8Y-DpiSE9q2z8bqwgJVpAZo,2697
7
+ job_shop_lib/benchmarking/__init__.py,sha256=BYCrJUNr_uk2c0xIbDt07OnUMhQx8Dudkukx3TFWxgw,3271
8
+ job_shop_lib/benchmarking/_load_benchmark.py,sha256=Jb6HYGKkub-3uU3l3NreRPE0PU6f0n8G9Mih5vMImOI,2936
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=vz_Kg_CmvZ13yGgqi-hZuFkosJR1v449xNaAZV3PhsE,10501
12
+ job_shop_lib/dispatching/__init__.py,sha256=2VQYWNSyuDx3zzrDPCEzs5VJd2AIJvF7vA7LwK5z2V4,1648
13
+ job_shop_lib/dispatching/_dispatcher.py,sha256=HW333xJoupufSUCg-pfaR_4KoQHjQMd4SBXJj-vgE7Y,22349
14
+ job_shop_lib/dispatching/_dispatcher_observer_config.py,sha256=RaUkLxYCHG8Tx2tPgFyOBa8FAcbREZdKuTyLsyaYvhA,2473
15
+ job_shop_lib/dispatching/_factories.py,sha256=1McCm3iJGdGDZerAe6MTWsthpbomuYb3crTKg_5lfyM,4678
16
+ job_shop_lib/dispatching/_history_observer.py,sha256=dixJe83quzGNwG0u0k2uES7GsLw0zWCjX0MOUD4VTRU,634
17
+ job_shop_lib/dispatching/_ready_operation_filters.py,sha256=H2-CPL0BKDvpLM2zvDGr9eC849qLgbxsVDHgPAHtNgc,5754
18
+ job_shop_lib/dispatching/_unscheduled_operations_observer.py,sha256=3E0ePesDdWdNs6520znnOBW3eiegJj5bZg9Tmb0xoSA,2705
19
+ job_shop_lib/dispatching/feature_observers/__init__.py,sha256=EuJLvSpJpoXUK8A4UuC2k6Mpa293ZR3oCnnvYivIBtU,2240
20
+ job_shop_lib/dispatching/feature_observers/_composite_feature_observer.py,sha256=5njpWV1Biui931HEuik9JGjsawle8fXaU5-mFYsxhRI,7933
21
+ job_shop_lib/dispatching/feature_observers/_duration_observer.py,sha256=fbkUIVScF1iNjdVCYr1ImQm53TfahvVnGXhsRAsgdzY,4129
22
+ job_shop_lib/dispatching/feature_observers/_earliest_start_time_observer.py,sha256=W5Tr81Kme8N-m85jmX7yVc65_xlwNQBvVjnjlL-aq7w,11493
23
+ job_shop_lib/dispatching/feature_observers/_factory.py,sha256=JRQLQ4SEXk7_beyzm0VcGQaL1j8NB1v7ZzsEh7NU3IM,3147
24
+ job_shop_lib/dispatching/feature_observers/_feature_observer.py,sha256=inFim_vKRk9_MTHURkr2ZLP1aJ1AHd3OQXqYg7VvCAo,8722
25
+ job_shop_lib/dispatching/feature_observers/_is_completed_observer.py,sha256=Dm67d90C-a-aZXDtRca1VakuYmLFXIl4vD9upr_1q6Q,4642
26
+ job_shop_lib/dispatching/feature_observers/_is_ready_observer.py,sha256=aP5CpwmCWP4w8J69qAC7QwGRQGMlfNbM31n-BRu92DA,1289
27
+ job_shop_lib/dispatching/feature_observers/_is_scheduled_observer.py,sha256=OcuMUB9_By6ZMtX-1_3z-xaxGbP85a5Zv0ywAv7XxWQ,1491
28
+ job_shop_lib/dispatching/feature_observers/_position_in_job_observer.py,sha256=WRknpQBKXs6h6cXLFJW7ZCvjtU8CPL-iXXNPw3g-mLE,1303
29
+ job_shop_lib/dispatching/feature_observers/_remaining_operations_observer.py,sha256=5V87lCrJUabEe8AkTGXPu5yS8OGxeN8L3-xNyHmdmLs,1441
30
+ job_shop_lib/dispatching/rules/__init__.py,sha256=p1rkqf66L62uvAOM1ZxNV8xHoh7SuYjHi_8ZNBvPIjg,1450
31
+ job_shop_lib/dispatching/rules/_dispatching_rule_factory.py,sha256=0Hht2i_aGS5hgwPxh_59-ZtNQxgSOwEFclukXH6Ib9U,2942
32
+ job_shop_lib/dispatching/rules/_dispatching_rule_solver.py,sha256=uvUtlcV4kg4XXu63MRHOWEg-QBMjRLE2G425-fyVPgE,6544
33
+ job_shop_lib/dispatching/rules/_dispatching_rules_functions.py,sha256=wfBdiKqEQQ8C5Gg_mrWWSuWncPwUkFacjeAQ8D4n9Wc,7648
34
+ job_shop_lib/dispatching/rules/_machine_chooser_factory.py,sha256=QqYXQr7Cp6WsqhLa1oHvR1vnbG8IFmYvxM44dQeLeSE,2362
35
+ job_shop_lib/dispatching/rules/_utils.py,sha256=DFDpRoHb56Rtn01vfN69Bq0X3F8P1EtM6trHx9aXg3U,4643
36
+ job_shop_lib/exceptions.py,sha256=ARzpoZJCvRIvOesCiqqFSRxkv6w9WwEXx0aBP-l2IKA,1597
37
+ job_shop_lib/generation/__init__.py,sha256=tgMVhnh62lkwGKywvingFD9SLhc-vERKiWsS-41qQKA,605
38
+ job_shop_lib/generation/_general_instance_generator.py,sha256=e-NDkH-NoCwa14oADj6n_I7BX5xWWVVzRLvb4rpJ92w,6374
39
+ job_shop_lib/generation/_instance_generator.py,sha256=VV0OKX4JgFq3I1EY6s3LrOdPjM3v4lH6S1hkUebTkFQ,4615
40
+ job_shop_lib/generation/_transformations.py,sha256=X-hTAJVIHZ3bmF1rqS0zCit8r5SGpHpV8Fcl92fejow,5336
41
+ job_shop_lib/generation/_utils.py,sha256=cBhGILE0FE3TqvWoHqpaFEffO8D2fb869pF-BdMlYsg,3617
42
+ job_shop_lib/graphs/__init__.py,sha256=zw4aOE-7QF8Lt8316rCUwOEAGqznjiijumTlGqBmfuw,1840
43
+ job_shop_lib/graphs/_build_disjunctive_graph.py,sha256=UbUYdeQaaeEqLchcKJGHEFGl4wElfGLb1o_R-u8wqnA,5120
44
+ job_shop_lib/graphs/_build_resource_task_graphs.py,sha256=GHUHkUNPxVf1miScgPPMe2YqlXFEMxIy5cDhNw7OZ1E,6954
45
+ job_shop_lib/graphs/_constants.py,sha256=K-GeVvh_DTWpo1KOX1clmxWS_pkUJbq19yOBmrCVIxI,1086
46
+ job_shop_lib/graphs/_job_shop_graph.py,sha256=mgawDY-PlEkGeTxoF0HaZCs0K514YH6zKFB0SssbJak,10761
47
+ job_shop_lib/graphs/_node.py,sha256=9TFH8C1D44W1IvOIG8MucLNQyLzasyBXVkMZTJU4rso,6075
48
+ job_shop_lib/graphs/graph_updaters/__init__.py,sha256=UhnZL55e3cAv7hVetB6bRmIOn8BDhG2bsbrdRoHtxLY,516
49
+ job_shop_lib/graphs/graph_updaters/_graph_updater.py,sha256=j1f7iWsa62GVszK2BPaMxnKBCEGWa9owm8g4VWUje8w,1967
50
+ job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py,sha256=SfgmDyMwfW56OBjJPaU76c42IsX5qx9j-eMtrv0DjKk,6047
51
+ job_shop_lib/graphs/graph_updaters/_utils.py,sha256=X5YfwJA1CCgpm1r9C036Gal2CkDh2SSak7wl7TbdjHw,704
52
+ job_shop_lib/reinforcement_learning/__init__.py,sha256=gOY-C6BMeFr3084MKMMbW0CoK7gMsaOYNsgnYuepswQ,1033
53
+ job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py,sha256=ib1Y6cItVvId4PfesiQ0XKbh9y6h8LVhD0gYDO4wSlk,15732
54
+ job_shop_lib/reinforcement_learning/_reward_observers.py,sha256=iWHccnujeAKyTQn2ilQ4BhcEccoSTyJqQ5yOiP5GG_Y,2984
55
+ job_shop_lib/reinforcement_learning/_single_job_shop_graph_env.py,sha256=DZnXeXmzMGKq-vwFhxukmSDN1UyrkUfbnjpjFtC9_Bs,15845
56
+ job_shop_lib/reinforcement_learning/_types_and_constants.py,sha256=xozdM_Wabdbe9e1a769p5980OSNBwQqc9yyaSGW2ODQ,1743
57
+ job_shop_lib/reinforcement_learning/_utils.py,sha256=ksg2ghSncxd0K3AR5hGS5PQejjd-Hgx6LGtXX_oatOc,2523
58
+ job_shop_lib/visualization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
+ job_shop_lib/visualization/gantt/__init__.py,sha256=HGXwRgDuMAldqU0JBdiZCd5e79XBz1r96qHeDVlzE54,1145
60
+ job_shop_lib/visualization/gantt/_gantt_chart_creator.py,sha256=LTsVhpB1Fb_2o08HRZPPXSekwzR7fyTSC6h549XMqhU,8638
61
+ job_shop_lib/visualization/gantt/_gantt_chart_video_and_gif_creation.py,sha256=CcHcvafYrTy7UaScM_wp9QlLOgKiTIKV7tFkttMgoLU,14474
62
+ job_shop_lib/visualization/gantt/_plot_gantt_chart.py,sha256=9-NSSNsVcW8gYLZtAuFeYURqi8cHNkVYufosKtbKFOI,6881
63
+ job_shop_lib/visualization/graphs/__init__.py,sha256=1kytwxBYwmf8ydPK74W07UT6F7gUHFy9sYPfloF0FqY,611
64
+ job_shop_lib/visualization/graphs/_plot_disjunctive_graph.py,sha256=4VBMYiFXXkCGSnGYN9iqNtWrbLJQxAMHojPHhAbdA0s,14387
65
+ job_shop_lib/visualization/graphs/_plot_resource_task_graph.py,sha256=RgJqHS5hJh3KkyaLbtpG_bER981BFRwGpflz7I7gS64,13271
66
+ job_shop_lib-1.0.0b1.dist-info/LICENSE,sha256=9mggivMGd5taAu3xbmBway-VQZMBzurBGHofFopvUsQ,1069
67
+ job_shop_lib-1.0.0b1.dist-info/METADATA,sha256=4HxsMEuSzkSdZDeMWbaMEd0M-QB3iEAoJ6e_t18ZdBc,16425
68
+ job_shop_lib-1.0.0b1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
69
+ job_shop_lib-1.0.0b1.dist-info/RECORD,,
@@ -1,276 +0,0 @@
1
- """Contains functions to plot the agent-task graph of a job shop instance.
2
-
3
- The agent-task graph was introduced by Junyoung Park et al. (2021).
4
- In contrast to the disjunctive graph, instead of connecting operations that
5
- share the same resources directly by disjunctive edges, operation nodes are
6
- connected with machine ones. All machine nodes are connected between them, and
7
- all operation nodes from the same job are connected by non-directed edges too.
8
-
9
- See: job_shop_lib.graphs.build_agent_task_graph module for more information.
10
- """
11
-
12
- from typing import Optional
13
-
14
- import matplotlib.pyplot as plt
15
- import networkx as nx
16
-
17
- from job_shop_lib.graphs import NodeType, JobShopGraph, Node
18
-
19
-
20
- def plot_agent_task_graph(
21
- job_shop_graph: JobShopGraph,
22
- title: Optional[str] = None,
23
- figsize: tuple[int, int] = (10, 10),
24
- layout: Optional[dict[Node, tuple[float, float]]] = None,
25
- color_map_name: str = "tab10",
26
- node_size: int = 1000,
27
- alpha: float = 0.95,
28
- add_legend: bool = False,
29
- ) -> plt.Figure:
30
- """Returns a plot of the agent-task graph of the instance.
31
-
32
- Machine and job nodes are represented by squares, and the operation nodes
33
- are represented by circles.
34
-
35
- Args:
36
- job_shop_graph:
37
- The job shop graph instance. It should be already initialized with
38
- the instance with a valid agent-task graph representation.
39
-
40
- Returns:
41
- The figure of the plot. This figure can be used to save the plot to a
42
- file or to show it in a Jupyter notebook.
43
- """
44
- if title is None:
45
- title = (
46
- f"Agent-Task Graph Visualization: {job_shop_graph.instance.name}"
47
- )
48
- # Create a new figure and axis
49
- fig, ax = plt.subplots(figsize=figsize)
50
- fig.suptitle(title)
51
-
52
- # Create the networkx graph
53
- graph = job_shop_graph.graph
54
- nodes = job_shop_graph.non_removed_nodes()
55
-
56
- # Create the layout if it was not provided
57
- if layout is None:
58
- layout = three_columns_layout(job_shop_graph)
59
-
60
- # Define colors and shapes
61
- color_map = plt.get_cmap(color_map_name)
62
- machine_colors = {
63
- machine.machine_id: color_map(i)
64
- for i, machine in enumerate(
65
- job_shop_graph.nodes_by_type[NodeType.MACHINE]
66
- )
67
- }
68
-
69
- node_colors = [
70
- _get_node_color(node, machine_colors) for node in job_shop_graph.nodes
71
- ] # We need to get the color of all nodes to avoid an index error
72
- node_shapes = {"machine": "s", "job": "d", "operation": "o", "global": "o"}
73
-
74
- # Draw nodes with different shapes based on their type
75
- for node_type, shape in node_shapes.items():
76
- current_nodes = [
77
- node.node_id
78
- for node in nodes
79
- if node.node_type.name.lower() == node_type
80
- ]
81
- nx.draw_networkx_nodes(
82
- graph,
83
- layout,
84
- nodelist=current_nodes,
85
- node_color=[node_colors[i] for i in current_nodes],
86
- node_shape=shape,
87
- ax=ax,
88
- node_size=node_size,
89
- alpha=alpha,
90
- )
91
-
92
- # Draw edges
93
- nx.draw_networkx_edges(graph, layout, ax=ax)
94
-
95
- node_labels = {node.node_id: _get_node_label(node) for node in nodes}
96
- nx.draw_networkx_labels(graph, layout, node_labels, ax=ax)
97
-
98
- ax.set_axis_off()
99
-
100
- plt.tight_layout()
101
-
102
- # Add to the legend the meaning of m and d
103
- if add_legend:
104
- plt.figtext(0, 0.95, "d = duration", wrap=True, fontsize=12)
105
- return fig
106
-
107
-
108
- def _get_node_color(
109
- node: Node, machine_colors: dict[int, tuple[float, float, float, float]]
110
- ) -> tuple[float, float, float, float] | str:
111
- if node.node_type == NodeType.OPERATION:
112
- return machine_colors[node.operation.machine_id]
113
- if node.node_type == NodeType.MACHINE:
114
- return machine_colors[node.machine_id]
115
-
116
- return "lightblue"
117
-
118
-
119
- def _get_node_label(node: Node) -> str:
120
- if node.node_type == NodeType.OPERATION:
121
- return f"d={node.operation.duration}"
122
- if node.node_type == NodeType.MACHINE:
123
- return f"M{node.machine_id}"
124
- if node.node_type == NodeType.JOB:
125
- return f"J{node.job_id}"
126
- if node.node_type == NodeType.GLOBAL:
127
- return "G"
128
-
129
- raise ValueError(f"Invalid node type: {node.node_type}")
130
-
131
-
132
- def three_columns_layout(
133
- job_shop_graph: JobShopGraph,
134
- *,
135
- leftmost_position: float = 0.1,
136
- rightmost_position: float = 0.9,
137
- topmost_position: float = 1.0,
138
- bottommost_position: float = 0.0,
139
- ) -> dict[Node, tuple[float, float]]:
140
- """Returns the layout of the agent-task graph.
141
-
142
- The layout is organized in a grid manner. For example, for a JobShopGraph
143
- representing a job shop instance with 2 machines and 3 jobs, the layout
144
- would be:
145
-
146
- 0: - O_11 -
147
- 1: - O_12 J1
148
- 2: - O_13 -
149
- 3: M1 O_21 -
150
- 4: - O_22 J2
151
- 5: - O_23 -
152
- 6: M2 O_31 -
153
- 7: - O_32 J3
154
- 8: - O_33 -
155
- 9: - - -
156
- 10: - G -
157
- Where M1 and M2 are the machine nodes, J1, J2, and J3 are the job
158
- nodes, O_ij are the operation nodes, and G is the global node.
159
-
160
- Args:
161
- job_shop_graph:
162
- The job shop graph instance. It should be already initialized with
163
- the instance with a valid agent-task graph representation.
164
- leftmost_position:
165
- The center position of the leftmost column of the layout. It should
166
- be a float between 0 and 1. The default is 0.1.
167
- rightmost_position:
168
- The center position of the rightmost column of the layout. It
169
- should be a float between 0 and 1. The default is 0.9.
170
- topmost_position:
171
- The center position of the topmost node of the layout. It should be
172
- a float between 0 and 1. The default is 0.9.
173
- bottommost_position:
174
- The center position of the bottommost node of the layout. It should
175
- be a float between 0 and 1. The default is 0.1.
176
-
177
- Returns:
178
- A dictionary with the position of each node in the graph. The keys are
179
- the node ids, and the values are tuples with the x and y coordinates.
180
- """
181
-
182
- x_positions = _get_x_positions(leftmost_position, rightmost_position)
183
-
184
- operation_nodes = [
185
- node
186
- for node in job_shop_graph.nodes_by_type[NodeType.OPERATION]
187
- if not job_shop_graph.is_removed(node)
188
- ]
189
- machine_nodes = [
190
- node
191
- for node in job_shop_graph.nodes_by_type[NodeType.MACHINE]
192
- if not job_shop_graph.is_removed(node)
193
- ]
194
- job_nodes = [
195
- node
196
- for node in job_shop_graph.nodes_by_type[NodeType.JOB]
197
- if not job_shop_graph.is_removed(node)
198
- ]
199
- global_nodes = [
200
- node
201
- for node in job_shop_graph.nodes_by_type[NodeType.GLOBAL]
202
- if not job_shop_graph.is_removed(node)
203
- ]
204
-
205
- # job_nodes = job_shop_graph.nodes_by_type[NodeType.JOB]
206
- # global_nodes = job_shop_graph.nodes_by_type[NodeType.GLOBAL]
207
-
208
- total_positions = len(operation_nodes) + len(global_nodes) * 2
209
- y_spacing = (topmost_position - bottommost_position) / total_positions
210
-
211
- layout: dict[Node, tuple[float, float]] = {}
212
-
213
- machines_spacing_multiplier = len(operation_nodes) // len(machine_nodes)
214
- layout.update(
215
- _assign_positions_from_top(
216
- machine_nodes,
217
- x_positions["machine"],
218
- topmost_position,
219
- y_spacing * machines_spacing_multiplier,
220
- )
221
- )
222
- layout.update(
223
- (
224
- _assign_positions_from_top(
225
- operation_nodes,
226
- x_positions["operation"],
227
- topmost_position,
228
- y_spacing,
229
- )
230
- )
231
- )
232
-
233
- if global_nodes:
234
- layout[global_nodes[0]] = (
235
- x_positions["operation"],
236
- bottommost_position,
237
- )
238
-
239
- if job_nodes:
240
- job_multiplier = len(operation_nodes) // len(job_nodes)
241
- layout.update(
242
- _assign_positions_from_top(
243
- job_nodes,
244
- x_positions["job"],
245
- topmost_position,
246
- y_spacing * job_multiplier,
247
- )
248
- )
249
- return layout
250
-
251
-
252
- def _get_x_positions(
253
- leftmost_position: float, rightmost_position: float
254
- ) -> dict[str, float]:
255
- center_position = (
256
- leftmost_position + (rightmost_position - leftmost_position) / 2
257
- )
258
- return {
259
- "machine": leftmost_position,
260
- "operation": center_position,
261
- "job": rightmost_position,
262
- }
263
-
264
-
265
- def _assign_positions_from_top(
266
- nodes: list[Node],
267
- x: float,
268
- top: float,
269
- y_spacing: float,
270
- ) -> dict[Node, tuple[float, float]]:
271
- layout: dict[Node, tuple[float, float]] = {}
272
- for i, node in enumerate(nodes):
273
- y = top - (i + 1) * y_spacing
274
- layout[node] = (x, y)
275
-
276
- return layout
@@ -1,66 +0,0 @@
1
- job_shop_lib/__init__.py,sha256=727ReBd86kZgmAYA8lkYhDRaAnqJ6iH6uBP-zIRbjw4,643
2
- job_shop_lib/_base_solver.py,sha256=p17XmtufNc9Y481cqZUT45pEkUmmW1HWG53dfhIBJH8,1363
3
- job_shop_lib/_job_shop_instance.py,sha256=OoKkZRQK6kbk0zgiXc-0mFk8t7aFpWK2Cah-vmI60AY,18321
4
- job_shop_lib/_operation.py,sha256=6YgAuqFQgvoGIYTkdsBh-b8mVlc0i9AIw8cqmiTXeHE,3809
5
- job_shop_lib/_schedule.py,sha256=QQ7orbpd00pTjJvsh8bNuRSEFJLst8B8GaCSB8JPXTY,11251
6
- job_shop_lib/_scheduled_operation.py,sha256=krjGn47VwsC7bXUTqlUq8Y-DpiSE9q2z8bqwgJVpAZo,2697
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=oMPeA2VHoYX1ZvmygQ8kYew40ITLAQATmM4OhgVFuXM,10482
12
- job_shop_lib/dispatching/__init__.py,sha256=2VQYWNSyuDx3zzrDPCEzs5VJd2AIJvF7vA7LwK5z2V4,1648
13
- job_shop_lib/dispatching/_dispatcher.py,sha256=uy4_EHdhwhGLWc1zv1AtY9FApP-70AdjCnLa3_q2nOQ,22316
14
- job_shop_lib/dispatching/_dispatcher_observer_config.py,sha256=034m83TsZXAb89nPxGRZm--0KSaGA9tJnr-7aYQs6tU,2479
15
- job_shop_lib/dispatching/_factories.py,sha256=D9m_tHUqQe-aGc50X_5HSm27nELwm4VyVEg6zUudkyg,4643
16
- job_shop_lib/dispatching/_history_observer.py,sha256=Vl8rQaxekUeEB-AyNxyC3c76zQakeh-rdri2iDnZvXw,610
17
- job_shop_lib/dispatching/_ready_operation_filters.py,sha256=Mywt57h8Nlj6XrptWakVt9n1Tq4jsneZFQEgjLMxJgw,5731
18
- job_shop_lib/dispatching/_unscheduled_operations_observer.py,sha256=LNEzqOWqEf6fvtkQrDmDWFEhCfA75OgEtzdomzbxYII,2683
19
- job_shop_lib/dispatching/feature_observers/__init__.py,sha256=EuJLvSpJpoXUK8A4UuC2k6Mpa293ZR3oCnnvYivIBtU,2240
20
- job_shop_lib/dispatching/feature_observers/_composite_feature_observer.py,sha256=HnvNQTXvCX5HAqBdYqzY-cPjeP0VcUxP6OTXvIlMulk,7876
21
- job_shop_lib/dispatching/feature_observers/_duration_observer.py,sha256=fbkUIVScF1iNjdVCYr1ImQm53TfahvVnGXhsRAsgdzY,4129
22
- job_shop_lib/dispatching/feature_observers/_earliest_start_time_observer.py,sha256=SOdXs-uzTzcLqOsmpbKvf-OGlGXOMVVJL9zgVVVDvF8,11442
23
- job_shop_lib/dispatching/feature_observers/_factory.py,sha256=PLbpiJDPQRcicxyrIaBeyWnJRPlMVLJixzB44C0SXYE,3171
24
- job_shop_lib/dispatching/feature_observers/_feature_observer.py,sha256=crbqG1KrmUOfG4z7shHNzhUg7-uSP4_RWxyOi-RRWmE,8635
25
- job_shop_lib/dispatching/feature_observers/_is_completed_observer.py,sha256=wG84zhmIWEXZjgT883Vz-onJZYpB7SJb2FsznEbkPQw,4592
26
- job_shop_lib/dispatching/feature_observers/_is_ready_observer.py,sha256=wy_pA-1wmnzVjhq92mdsT2JJHYbfsm79mcMgSgYUCOs,1264
27
- job_shop_lib/dispatching/feature_observers/_is_scheduled_observer.py,sha256=OcuMUB9_By6ZMtX-1_3z-xaxGbP85a5Zv0ywAv7XxWQ,1491
28
- job_shop_lib/dispatching/feature_observers/_position_in_job_observer.py,sha256=WRknpQBKXs6h6cXLFJW7ZCvjtU8CPL-iXXNPw3g-mLE,1303
29
- job_shop_lib/dispatching/feature_observers/_remaining_operations_observer.py,sha256=5V87lCrJUabEe8AkTGXPu5yS8OGxeN8L3-xNyHmdmLs,1441
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=goO3wl5NY9mjRr6d3KBaImA7gpseFDawdZdRhkIM5bM,6349
33
- job_shop_lib/dispatching/rules/_dispatching_rules_functions.py,sha256=yRJXYH6QSxDCIK8vqNUfMCMpzWmr3j_camAR72Z6D9Q,7605
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=uqSYzP6vW1SgmaRrTP1svjq-nPQXNJeXcKVW6gp9sdI,7318
39
- job_shop_lib/generation/_instance_generator.py,sha256=e_A7lSV5IMG2vPeANp50S5bg19XrhiQ9rvzOP-US1l0,4504
40
- job_shop_lib/generation/_transformations.py,sha256=ZigQTBsS3xgB2FhBu9MpsFs7A-_VY3840V_RtOIhCBk,5296
41
- job_shop_lib/graphs/__init__.py,sha256=GEtrWjbeFEFpvNytlvqEU6ZUPZP7qX-71N659f9r2u8,1818
42
- job_shop_lib/graphs/_build_agent_task_graph.py,sha256=6mvWJ7fFD5CmxkTuXEwY7f_-qxjKdNgFmWk4a4mgiD8,7132
43
- job_shop_lib/graphs/_build_disjunctive_graph.py,sha256=UbUYdeQaaeEqLchcKJGHEFGl4wElfGLb1o_R-u8wqnA,5120
44
- job_shop_lib/graphs/_constants.py,sha256=K-GeVvh_DTWpo1KOX1clmxWS_pkUJbq19yOBmrCVIxI,1086
45
- job_shop_lib/graphs/_job_shop_graph.py,sha256=Fv0TOwtmjqdhH-A_TBH0wSzQkGgqTyc7vvEcfzbQiwA,10681
46
- job_shop_lib/graphs/_node.py,sha256=hGgdnD9wlsTbkaDizFZMsxPXa2-m91iBNLu0vtkVbxw,6034
47
- job_shop_lib/graphs/graph_updaters/__init__.py,sha256=UhnZL55e3cAv7hVetB6bRmIOn8BDhG2bsbrdRoHtxLY,516
48
- job_shop_lib/graphs/graph_updaters/_graph_updater.py,sha256=j1f7iWsa62GVszK2BPaMxnKBCEGWa9owm8g4VWUje8w,1967
49
- job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py,sha256=Sli9YpbtKlAvjEQxbc6gS1kOZneBD7RPqm_DagtJFe4,6009
50
- job_shop_lib/graphs/graph_updaters/_utils.py,sha256=X5YfwJA1CCgpm1r9C036Gal2CkDh2SSak7wl7TbdjHw,704
51
- job_shop_lib/reinforcement_learning/__init__.py,sha256=gOY-C6BMeFr3084MKMMbW0CoK7gMsaOYNsgnYuepswQ,1033
52
- job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py,sha256=N28SslcKBguhILQxisc7NIuR3XVnMrj1dzBSEKA8AdE,14865
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=_qZ69kvgpBUoRJDL0SYDxj3Lq6_8HT3MDaxJndqgon0,12970
55
- job_shop_lib/reinforcement_learning/_types_and_constants.py,sha256=5lvjXihMrj2ziLlquLXQxtwzjLM5yo7Ny8kPo-aCmlQ,1737
56
- job_shop_lib/reinforcement_learning/_utils.py,sha256=ilI089Bs8CRlfRV_yH6XH8oypTDtRa7hS-H4iRCC5lU,2497
57
- job_shop_lib/visualization/__init__.py,sha256=K85MQdAbsguvoH99NX9sxZP458jDXSljpzQiS_4-dlU,1587
58
- job_shop_lib/visualization/_gantt_chart_creator.py,sha256=p7W7OaLoHO5xdlNaJXQVBweszb2bNuM6oP9TAhNgwss,8600
59
- job_shop_lib/visualization/_gantt_chart_video_and_gif_creation.py,sha256=aPy7y0oZlEQUzoYQnagiRi_2C-80WY29HR2KpekS6wQ,14384
60
- job_shop_lib/visualization/_plot_agent_task_graph.py,sha256=AaBTD_S34WjrsZnL_iMAplR_f67RahZi7x58SOvp-q0,8834
61
- job_shop_lib/visualization/_plot_disjunctive_graph.py,sha256=Vo3c2oHQ8YkLbwrDr76zh4yzCuQk-gkVeyWN-7Zj71o,14279
62
- job_shop_lib/visualization/_plot_gantt_chart.py,sha256=1WCJ5Gjl3dwA-w4Jn9suIg-ZGR28yYUAy8Jp-IiyvfI,6842
63
- job_shop_lib-1.0.0a5.dist-info/LICENSE,sha256=9mggivMGd5taAu3xbmBway-VQZMBzurBGHofFopvUsQ,1069
64
- job_shop_lib-1.0.0a5.dist-info/METADATA,sha256=R-7tM_SWNJV6JoTtDh_FlO6SbD-fXQt36Ro0KZAzLKk,16184
65
- job_shop_lib-1.0.0a5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
66
- job_shop_lib-1.0.0a5.dist-info/RECORD,,