job-shop-lib 0.4.0__py3-none-any.whl → 0.5.0__py3-none-any.whl

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.
@@ -27,7 +27,8 @@ def create_gif(
27
27
  instance: JobShopInstance,
28
28
  solver: DispatchingRuleSolver,
29
29
  plot_function: (
30
- Callable[[Schedule, int, list[Operation] | None], Figure] | None
30
+ Callable[[Schedule, int, list[Operation] | None, int | None], Figure]
31
+ | None
31
32
  ) = None,
32
33
  fps: int = 1,
33
34
  remove_frames: bool = True,
@@ -80,50 +81,59 @@ def plot_gantt_chart_wrapper(
80
81
  title: str | None = None,
81
82
  cmap: str = "viridis",
82
83
  show_available_operations: bool = False,
83
- ) -> Callable[[Schedule, int, list[Operation] | None], Figure]:
84
+ ) -> Callable[[Schedule, int, list[Operation] | None, int | None], Figure]:
84
85
  """Returns a function that plots a Gantt chart for an unfinished schedule.
85
86
 
86
87
  Args:
87
88
  title: The title of the Gantt chart.
88
89
  cmap: The name of the colormap to use.
90
+ show_available_operations:
91
+ Whether to show the available operations in the Gantt chart.
89
92
 
90
93
  Returns:
91
94
  A function that plots a Gantt chart for a schedule. The function takes
92
- a `Schedule` object and the makespan of the schedule as input and
93
- returns a `Figure` object.
95
+ the following arguments:
96
+ - schedule: The schedule to plot.
97
+ - makespan: The makespan of the schedule.
98
+ - available_operations: A list of available operations. If None,
99
+ the available operations are not shown.
100
+ - current_time: The current time in the schedule. If provided, a
101
+ red vertical line is plotted at this time.
94
102
  """
95
103
 
96
104
  def plot_function(
97
105
  schedule: Schedule,
98
106
  makespan: int,
99
107
  available_operations: list | None = None,
108
+ current_time: int | None = None,
100
109
  ) -> Figure:
101
110
  fig, ax = plot_gantt_chart(
102
111
  schedule, title=title, cmap_name=cmap, xlim=makespan
103
112
  )
104
113
 
105
- if not show_available_operations or available_operations is None:
106
- return fig
107
-
108
- operations_text = "\n".join(
109
- str(operation) for operation in available_operations
110
- )
111
- text = f"Available operations:\n{operations_text}"
112
- # Print the available operations at the bottom right corner
113
- # of the Gantt chart
114
- fig.text(
115
- 1.25,
116
- 0.05,
117
- text,
118
- ha="right",
119
- va="bottom",
120
- transform=ax.transAxes,
121
- bbox={
122
- "facecolor": "white",
123
- "alpha": 0.5,
124
- "boxstyle": "round,pad=0.5",
125
- },
126
- )
114
+ if show_available_operations and available_operations is not None:
115
+
116
+ operations_text = "\n".join(
117
+ str(operation) for operation in available_operations
118
+ )
119
+ text = f"Available operations:\n{operations_text}"
120
+ # Print the available operations at the bottom right corner
121
+ # of the Gantt chart
122
+ fig.text(
123
+ 1.25,
124
+ 0.05,
125
+ text,
126
+ ha="right",
127
+ va="bottom",
128
+ transform=ax.transAxes,
129
+ bbox={
130
+ "facecolor": "white",
131
+ "alpha": 0.5,
132
+ "boxstyle": "round,pad=0.5",
133
+ },
134
+ )
135
+ if current_time is not None:
136
+ ax.axvline(current_time, color="red", linestyle="--")
127
137
  return fig
128
138
 
129
139
  return plot_function
@@ -133,7 +143,9 @@ def create_gantt_chart_frames(
133
143
  frames_dir: str,
134
144
  instance: JobShopInstance,
135
145
  solver: DispatchingRuleSolver,
136
- plot_function: Callable[[Schedule, int, list[Operation] | None], Figure],
146
+ plot_function: Callable[
147
+ [Schedule, int, list[Operation] | None, int | None], Figure
148
+ ],
137
149
  plot_current_time: bool = True,
138
150
  ) -> None:
139
151
  """Creates frames of the Gantt chart for the schedule being built.
@@ -150,7 +162,8 @@ def create_gantt_chart_frames(
150
162
  should take a `Schedule` object and the makespan of the schedule as
151
163
  input and return a `Figure` object.
152
164
  plot_current_time:
153
- Whether to plot a vertical line at the current time."""
165
+ Whether to plot a vertical line at the current time.
166
+ """
154
167
  dispatcher = Dispatcher(instance, pruning_function=solver.pruning_function)
155
168
  history_tracker = HistoryTracker(dispatcher)
156
169
  makespan = solver.solve(instance, dispatcher).makespan()
@@ -160,23 +173,19 @@ def create_gantt_chart_frames(
160
173
  dispatcher.dispatch(
161
174
  scheduled_operation.operation, scheduled_operation.machine_id
162
175
  )
176
+ current_time = (
177
+ None if not plot_current_time else dispatcher.current_time()
178
+ )
163
179
  fig = plot_function(
164
180
  dispatcher.schedule,
165
181
  makespan,
166
182
  dispatcher.available_operations(),
183
+ current_time,
167
184
  )
168
- current_time = (
169
- None if not plot_current_time else dispatcher.current_time()
170
- )
171
- _save_frame(fig, frames_dir, i, current_time)
172
-
185
+ _save_frame(fig, frames_dir, i)
173
186
 
174
- def _save_frame(
175
- figure: Figure, frames_dir: str, number: int, current_time: int | None
176
- ) -> None:
177
- if current_time is not None:
178
- figure.gca().axvline(current_time, color="red", linestyle="--")
179
187
 
188
+ def _save_frame(figure: Figure, frames_dir: str, number: int) -> None:
180
189
  figure.savefig(f"{frames_dir}/frame_{number:02d}.png", bbox_inches="tight")
181
190
  plt.close(figure)
182
191
 
@@ -65,7 +65,7 @@ def _plot_machine_schedules(
65
65
  ) -> dict[int, Patch]:
66
66
  """Plots the schedules for each machine."""
67
67
  max_job_id = schedule.instance.num_jobs - 1
68
- cmap = plt.cm.get_cmap(cmap_name, max_job_id + 1)
68
+ cmap = plt.get_cmap(cmap_name, max_job_id + 1)
69
69
  norm = Normalize(vmin=0, vmax=max_job_id)
70
70
  legend_handles = {}
71
71
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: job-shop-lib
3
- Version: 0.4.0
3
+ Version: 0.5.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
@@ -15,7 +15,8 @@ Provides-Extra: pygraphviz
15
15
  Requires-Dist: imageio (>=2,<3)
16
16
  Requires-Dist: matplotlib (>=3,<4)
17
17
  Requires-Dist: networkx (>=3,<4)
18
- Requires-Dist: ortools (>=9,<10)
18
+ Requires-Dist: numpy (>=1.26.4,<2.0.0)
19
+ Requires-Dist: ortools (>=9.9,<9.10)
19
20
  Requires-Dist: pyarrow (>=15.0.0,<16.0.0)
20
21
  Requires-Dist: pygraphviz (>=1.12,<2.0) ; extra == "pygraphviz"
21
22
  Description-Content-Type: text/markdown
@@ -83,7 +84,7 @@ ft06 = load_benchmark_instance("ft06")
83
84
  ```
84
85
 
85
86
  The module `benchmarks` contains functions to load the instances from the file and return them as `JobShopInstance` objects without having to download them
86
- manually. The instances are stored in [benchmark_instances.json](job_shop_lib/benchmarks/benchmark_instances.json).
87
+ manually.
87
88
 
88
89
  The contributions to this benchmark dataset are as follows:
89
90
 
@@ -171,13 +172,15 @@ class DispatchingRule(str, Enum):
171
172
  We can visualize the solution with a `DispatchingRuleSolver` as a gif:
172
173
 
173
174
  ```python
174
- from job_shop_lib.visualization import create_gif, get_plot_function
175
+ from job_shop_lib.visualization import create_gif, plot_gantt_chart_wrapper
175
176
  from job_shop_lib.dispatching import DispatchingRuleSolver, DispatchingRule
176
177
 
177
178
  plt.style.use("ggplot")
178
179
 
179
180
  mwkr_solver = DispatchingRuleSolver("most_work_remaining")
180
- plot_function = get_plot_function(title="Solution with Most Work Remaining Rule")
181
+ plot_function = plot_gantt_chart_wrapper(
182
+ title="Solution with Most Work Remaining Rule"
183
+ )
181
184
  create_gif(
182
185
  gif_path="ft06_optimized.gif",
183
186
  instance=ft06,
@@ -350,3 +353,4 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
350
353
  Journal of Operational Research, vol. 64, no. 2, pp. 278–285, 1993.
351
354
 
352
355
  - Park, Junyoung, Sanjar Bakhtiyar, and Jinkyoo Park. "ScheduleNet: Learn to solve multi-agent scheduling problems with reinforcement learning." arXiv preprint arXiv:2106.03051, 2021.
356
+
@@ -6,10 +6,21 @@ job_shop_lib/benchmarking/load_benchmark.py,sha256=CjiSALutgWcfD-SDU6w9WO3udvPVp
6
6
  job_shop_lib/cp_sat/__init__.py,sha256=DqrF9IewFMkVB5BhFOHhlJvG6w6BW4ecxBXySunGLoU,97
7
7
  job_shop_lib/cp_sat/ortools_solver.py,sha256=zsISUQy0dQvn7bmUsAQBCe-V92CFskJHkSfngSP4KSg,8130
8
8
  job_shop_lib/dispatching/__init__.py,sha256=xk6NjndZ4-EH5G_fGSEX4LQEXL53TRYn5dKEb5uFggI,1568
9
- job_shop_lib/dispatching/dispatcher.py,sha256=2rzvmn6EQz2gIS8tP2tUPJ34uUq7SZzJubHmrjw_qV8,12394
9
+ job_shop_lib/dispatching/dispatcher.py,sha256=3WdShJtVMP4ZBeoOIegelTXziJLpEjtonAku21yqr20,19299
10
10
  job_shop_lib/dispatching/dispatching_rule_solver.py,sha256=fbNfSclH6Jw1F-QGY1oxAj9wm2hHhJHGnsF2HateXX8,4669
11
11
  job_shop_lib/dispatching/dispatching_rules.py,sha256=SIDkPx_1uTkM0loEqGMqotLBBSaGi1gH0WS85GXrT_I,5557
12
12
  job_shop_lib/dispatching/factories.py,sha256=ldyIbz3QuLuDkrqbgJXV6YoM6AV6CKyHu8z4hXLG2Vo,7267
13
+ job_shop_lib/dispatching/feature_observers/__init__.py,sha256=j7GXFCKK0mLjGc3M6bw2vePZaLyou_9BUjlHtAMriHc,1023
14
+ job_shop_lib/dispatching/feature_observers/composite_feature_observer.py,sha256=wLd5yirDekg_pFrBPWIyxKou8htimvKhtDbz0cJ8SKE,3302
15
+ job_shop_lib/dispatching/feature_observers/duration_observer.py,sha256=EMSfRsWkx94VeOF6v1f2s73hrEQ696vkFoWVVw5tWZ8,3804
16
+ job_shop_lib/dispatching/feature_observers/earliest_start_time_observer.py,sha256=pKrxaLOPHMnf-eniDhkPWVzzRpKLnpbXAeORqEmsrp0,6296
17
+ job_shop_lib/dispatching/feature_observers/factory.py,sha256=XF5spNp8T-dnPPnpWQ5dxuG7vrHLf-Wb8MP1tn4_BXA,1941
18
+ job_shop_lib/dispatching/feature_observers/feature_observer.py,sha256=q2i50LOhgjaQtu_0-3VlSH64uHcf73JddjcGijeKCVk,3646
19
+ job_shop_lib/dispatching/feature_observers/is_completed_observer.py,sha256=6UCxp-QLXxbw_1nppQJuG_qZZvjtGugYTxQdPTcIcgo,4086
20
+ job_shop_lib/dispatching/feature_observers/is_ready_observer.py,sha256=km75Pa8vd55grjvr7X-8e0K9vfxVWfms1ea6kAesKLo,1405
21
+ job_shop_lib/dispatching/feature_observers/is_scheduled_observer.py,sha256=PeLxPVLJX_TP4TG8ViEQFR8WS43wIp6CqyuapM8lIt8,1477
22
+ job_shop_lib/dispatching/feature_observers/position_in_job_observer.py,sha256=PEC-WwcyeHL8WOACElImDtAAoaf7MroaD9x5QlQddVE,1344
23
+ job_shop_lib/dispatching/feature_observers/remaining_operations_observer.py,sha256=yVde9gC0cheFNCoPa1lFgGSmzyew-zOGA98nZpBBw1I,1891
13
24
  job_shop_lib/dispatching/history_tracker.py,sha256=3jSh7pKEGiOcEK6bXK8AQJK4NtASxTknRjmHRKenxt8,649
14
25
  job_shop_lib/dispatching/pruning_functions.py,sha256=d94_uBHuESp4NSf_jBk1q8eBCfTPuU9meiL3StiqJiA,4378
15
26
  job_shop_lib/exceptions.py,sha256=0Wla1lK6E2u1o3t2hJj9hUwyoJ-1ebkXd42GdXFAhV0,899
@@ -18,20 +29,20 @@ job_shop_lib/generators/basic_generator.py,sha256=pbRDQWC2mnHU0dbc-T8wkdwVeJPlRn
18
29
  job_shop_lib/generators/transformations.py,sha256=FI2qHrETATJUrQP3-RYhZAQ5boyEZ0CF2StDbacBej8,5290
19
30
  job_shop_lib/graphs/__init__.py,sha256=mWyF0MypyYfvFhy2F93BJkFIVsxS_0ZqvPuc29B7TJg,1454
20
31
  job_shop_lib/graphs/build_agent_task_graph.py,sha256=ktj-oNLUPmWHfL81EVyaoF4hXClWYfnN7oG2Nn4pOsg,7128
21
- job_shop_lib/graphs/build_disjunctive_graph.py,sha256=IRMBtHw8aru5rYGz796-dc6QyaLJFh4LlPlN_BPSq5c,2877
32
+ job_shop_lib/graphs/build_disjunctive_graph.py,sha256=z1jiuTTaWPJZj-vSZdo064quGx4LEDKjtZIb1FieZW4,3705
22
33
  job_shop_lib/graphs/constants.py,sha256=dqPF--okue5sF70Iv-YR14QKFx4pxPwT2dL1Rh5jylM,374
23
34
  job_shop_lib/graphs/job_shop_graph.py,sha256=B0buqcg7US6UvIRWsoY8_FwqzPa_nVjnBu7hPIrygUo,7404
24
35
  job_shop_lib/graphs/node.py,sha256=FrSndtvqgRbN69jIcU6q1TkBh-LOGg8sxxYjDZqCcf4,5613
25
- job_shop_lib/job_shop_instance.py,sha256=ZB0NOcTvGSq0zmmxiDceaC0DH9ljpJXD0hfKOmP0jcE,12801
36
+ job_shop_lib/job_shop_instance.py,sha256=awEZ-xKM4yPlD4gE8SdfQdt68CWX_R3IebeVY8ST4bs,16376
26
37
  job_shop_lib/operation.py,sha256=S61x0xgu09JLwrRp7syd1P2psbl0ByGuK_hHoHp4ng8,3916
27
38
  job_shop_lib/schedule.py,sha256=aODGwMv9slFIqOTCz2hF_EIpXhddz8-iAH5gSzGO5G8,10393
28
39
  job_shop_lib/scheduled_operation.py,sha256=qzXzat1dQBbQ-sLyoG1iXbF9eWbdFeZDFjhAFVavHPk,3526
29
40
  job_shop_lib/visualization/__init__.py,sha256=Kxjk3ERYXPAHR72nkD92gFdJltSLA2kxLZrlZzZJS8o,693
30
41
  job_shop_lib/visualization/agent_task_graph.py,sha256=G-c9eiawz6m9sdnDM1r-ZHz6K-gYDIAreHpb6pkYE7w,8284
31
- job_shop_lib/visualization/create_gif.py,sha256=KrwMpSYvSCsL5Ld3taiNHSl_QDrODLpqM-MKQG_C2oU,6674
42
+ job_shop_lib/visualization/create_gif.py,sha256=aUB_2ChyFNo4KuKiQl2ANYmVB5NFcGb7pxKeqr0CVJQ,7186
32
43
  job_shop_lib/visualization/disjunctive_graph.py,sha256=pg4KG9BfQbnBPnXYgbyPGe0AuHSmhYqPeqWYAf_spWQ,5905
33
- job_shop_lib/visualization/gantt_chart.py,sha256=OyBMBnjSsRC769qXimJ3IIQWlssgPfx-nlVeSeU5sWY,4415
34
- job_shop_lib-0.4.0.dist-info/LICENSE,sha256=9mggivMGd5taAu3xbmBway-VQZMBzurBGHofFopvUsQ,1069
35
- job_shop_lib-0.4.0.dist-info/METADATA,sha256=nWD2fekWRXglydO3tihH7tLHvYVhILm_TASf-Yn82qA,12624
36
- job_shop_lib-0.4.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
37
- job_shop_lib-0.4.0.dist-info/RECORD,,
44
+ job_shop_lib/visualization/gantt_chart.py,sha256=B9sn4XrEUqgQhRKju-1VUG5R67AZXRu7jbrtA8VcndU,4412
45
+ job_shop_lib-0.5.0.dist-info/LICENSE,sha256=9mggivMGd5taAu3xbmBway-VQZMBzurBGHofFopvUsQ,1069
46
+ job_shop_lib-0.5.0.dist-info/METADATA,sha256=a_AtBz1LwmfrEoIVWXepewPFx2Pa1QiFJt857kCGncw,12582
47
+ job_shop_lib-0.5.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
48
+ job_shop_lib-0.5.0.dist-info/RECORD,,