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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,,