job-shop-lib 1.0.0a2__py3-none-any.whl → 1.0.0a4__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- job_shop_lib/_job_shop_instance.py +119 -55
- job_shop_lib/_operation.py +18 -7
- job_shop_lib/_schedule.py +13 -15
- job_shop_lib/_scheduled_operation.py +17 -18
- job_shop_lib/dispatching/__init__.py +4 -0
- job_shop_lib/dispatching/_dispatcher.py +36 -47
- job_shop_lib/dispatching/_dispatcher_observer_config.py +15 -2
- job_shop_lib/dispatching/_factories.py +10 -2
- job_shop_lib/dispatching/_ready_operation_filters.py +80 -0
- job_shop_lib/dispatching/feature_observers/_composite_feature_observer.py +0 -1
- job_shop_lib/dispatching/feature_observers/_factory.py +21 -18
- job_shop_lib/dispatching/feature_observers/_is_completed_observer.py +1 -0
- job_shop_lib/dispatching/feature_observers/_is_ready_observer.py +1 -1
- job_shop_lib/dispatching/rules/_dispatching_rule_solver.py +44 -25
- job_shop_lib/dispatching/rules/_dispatching_rules_functions.py +9 -9
- job_shop_lib/generation/_general_instance_generator.py +33 -34
- job_shop_lib/generation/_instance_generator.py +14 -17
- job_shop_lib/generation/_transformations.py +11 -8
- job_shop_lib/graphs/__init__.py +3 -0
- job_shop_lib/graphs/_build_disjunctive_graph.py +41 -3
- job_shop_lib/graphs/graph_updaters/_graph_updater.py +11 -13
- job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py +17 -20
- job_shop_lib/reinforcement_learning/__init__.py +16 -7
- job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py +69 -57
- job_shop_lib/reinforcement_learning/_single_job_shop_graph_env.py +43 -32
- job_shop_lib/reinforcement_learning/_types_and_constants.py +2 -2
- job_shop_lib/visualization/__init__.py +29 -10
- job_shop_lib/visualization/_gantt_chart_creator.py +122 -84
- job_shop_lib/visualization/_gantt_chart_video_and_gif_creation.py +68 -37
- job_shop_lib/visualization/_plot_disjunctive_graph.py +382 -0
- job_shop_lib/visualization/{_gantt_chart.py → _plot_gantt_chart.py} +78 -14
- {job_shop_lib-1.0.0a2.dist-info → job_shop_lib-1.0.0a4.dist-info}/METADATA +15 -3
- {job_shop_lib-1.0.0a2.dist-info → job_shop_lib-1.0.0a4.dist-info}/RECORD +36 -36
- {job_shop_lib-1.0.0a2.dist-info → job_shop_lib-1.0.0a4.dist-info}/WHEEL +1 -1
- job_shop_lib/visualization/_disjunctive_graph.py +0 -210
- /job_shop_lib/visualization/{_agent_task_graph.py → _plot_agent_task_graph.py} +0 -0
- {job_shop_lib-1.0.0a2.dist-info → job_shop_lib-1.0.0a4.dist-info}/LICENSE +0 -0
@@ -1,7 +1,6 @@
|
|
1
1
|
"""Home of the `GanttChartCreator` class and its configuration types."""
|
2
2
|
|
3
3
|
from typing import TypedDict
|
4
|
-
|
5
4
|
import matplotlib.pyplot as plt
|
6
5
|
|
7
6
|
from job_shop_lib.dispatching import (
|
@@ -10,62 +9,92 @@ from job_shop_lib.dispatching import (
|
|
10
9
|
)
|
11
10
|
from job_shop_lib.visualization import (
|
12
11
|
create_gantt_chart_video,
|
13
|
-
|
14
|
-
|
12
|
+
get_partial_gantt_chart_plotter,
|
13
|
+
create_gantt_chart_gif,
|
15
14
|
)
|
16
15
|
|
17
16
|
|
18
|
-
class
|
19
|
-
"""
|
20
|
-
`
|
17
|
+
class PartialGanttChartPlotterConfig(TypedDict, total=False):
|
18
|
+
"""A dictionary with the configuration for creating the
|
19
|
+
:class:`PartialGanttChartPlotter` function.
|
20
|
+
|
21
|
+
.. seealso::
|
22
|
+
|
23
|
+
- :class:`PartialGanttChartPlotter`
|
24
|
+
- :func:`get_partial_gantt_chart_plotter`
|
25
|
+
"""
|
21
26
|
|
22
27
|
title: str | None
|
28
|
+
"""The title of the Gantt chart."""
|
29
|
+
|
23
30
|
cmap: str
|
31
|
+
"""The colormap to use in the Gantt chart."""
|
32
|
+
|
24
33
|
show_available_operations: bool
|
34
|
+
"""Whether to show available operations in each step."""
|
25
35
|
|
26
36
|
|
27
|
-
|
28
|
-
|
29
|
-
|
37
|
+
class GifConfig(TypedDict, total=False):
|
38
|
+
"""A dictionary with the configuration for creating the GIF using the
|
39
|
+
:func:`create_gantt_chart_gif` function.
|
30
40
|
|
31
|
-
|
41
|
+
.. seealso::
|
32
42
|
|
43
|
+
:func:`create_gantt_chart_gif`
|
44
|
+
"""
|
33
45
|
|
34
|
-
|
35
|
-
"""
|
46
|
+
gif_path: str | None
|
47
|
+
"""The path to save the GIF. It must end with '.gif'."""
|
36
48
|
|
37
49
|
fps: int
|
50
|
+
"""The frames per second of the GIF. Defaults to 1."""
|
51
|
+
|
38
52
|
remove_frames: bool
|
39
|
-
|
40
|
-
plot_current_time: bool
|
53
|
+
"""Whether to remove the frames after creating the GIF."""
|
41
54
|
|
55
|
+
frames_dir: str | None
|
56
|
+
"""The directory to store the frames."""
|
42
57
|
|
43
|
-
|
44
|
-
"""
|
45
|
-
function."""
|
58
|
+
plot_current_time: bool
|
59
|
+
"""Whether to plot the current time in the Gantt chart."""
|
46
60
|
|
47
61
|
|
48
62
|
class VideoConfig(TypedDict, total=False):
|
49
63
|
"""Configuration for creating the video using the
|
50
|
-
`
|
64
|
+
:func:`create_gantt_chart_video` function.
|
65
|
+
|
66
|
+
.. seealso::
|
67
|
+
|
68
|
+
:func:`create_gantt_chart_video`
|
69
|
+
"""
|
51
70
|
|
52
71
|
video_path: str | None
|
72
|
+
"""The path to save the video. It must end with a valid video extension
|
73
|
+
(e.g., '.mp4')."""
|
74
|
+
|
53
75
|
fps: int
|
76
|
+
"""The frames per second of the video. Defaults to 1."""
|
77
|
+
|
54
78
|
remove_frames: bool
|
79
|
+
"""Whether to remove the frames after creating the video."""
|
80
|
+
|
55
81
|
frames_dir: str | None
|
82
|
+
"""The directory to store the frames."""
|
83
|
+
|
56
84
|
plot_current_time: bool
|
85
|
+
"""Whether to plot the current time in the Gantt chart."""
|
57
86
|
|
58
87
|
|
59
88
|
class GanttChartCreator:
|
60
89
|
"""Facade class that centralizes the creation of Gantt charts, videos
|
61
90
|
and GIFs.
|
62
91
|
|
63
|
-
It leverages a
|
64
|
-
scheduled and provides methods to plot the current state
|
65
|
-
of the schedule as a Gantt chart and to create a GIF that shows
|
66
|
-
evolution of the schedule over time.
|
92
|
+
It leverages a :class:`HistoryObserver` to keep track of the operations
|
93
|
+
being scheduled and provides methods to plot the current state
|
94
|
+
of the schedule as a Gantt chart and to create a GIF or video that shows
|
95
|
+
the evolution of the schedule over time.
|
67
96
|
|
68
|
-
It adds a new
|
97
|
+
It adds a new :class:`HistoryObserver` to the dispatcher if it does
|
69
98
|
not have one already. Otherwise, it uses the observer already present.
|
70
99
|
|
71
100
|
Attributes:
|
@@ -81,72 +110,80 @@ class GanttChartCreator:
|
|
81
110
|
Configuration for creating the video.
|
82
111
|
plot_function:
|
83
112
|
The function used to plot the Gantt chart when creating the GIF
|
84
|
-
or video. Created using the `
|
113
|
+
or video. Created using the :func:`get_partial_gantt_chart_plotter`
|
114
|
+
function.
|
115
|
+
|
116
|
+
Args:
|
117
|
+
dispatcher:
|
118
|
+
The :class:`Dispatcher` class that will be tracked using a
|
119
|
+
:class:`HistoryObserver`.
|
120
|
+
partial_gantt_chart_plotter_config:
|
121
|
+
Configuration for the Gantt chart wrapper function through the
|
122
|
+
:class:`PartialGanttChartPlotterConfig` class. Defaults to
|
123
|
+
``None``. Valid keys are:
|
124
|
+
|
125
|
+
- title: The title of the Gantt chart.
|
126
|
+
- cmap: The name of the colormap to use.
|
127
|
+
- show_available_operations: Whether to show available
|
128
|
+
operations in each step.
|
129
|
+
|
130
|
+
If ``title`` or ``cmap`` are not provided here and
|
131
|
+
``infer_gantt_chart_config`` is set to ``True``, the values from
|
132
|
+
``gantt_chart_config`` will be used if they are present.
|
133
|
+
|
134
|
+
.. seealso::
|
135
|
+
|
136
|
+
- :class:`PartialGanttChartPlotterConfig`
|
137
|
+
- :func:`get_partial_gantt_chart_plotter`
|
138
|
+
- :class:`PartialGanttChartPlotter`
|
139
|
+
|
140
|
+
gif_config:
|
141
|
+
Configuration for creating the GIF. Defaults to ``None``.
|
142
|
+
Valid keys are:
|
143
|
+
|
144
|
+
- gif_path: The path to save the GIF.
|
145
|
+
- fps: The frames per second of the GIF.
|
146
|
+
- remove_frames: Whether to remove the frames after creating
|
147
|
+
the GIF.
|
148
|
+
- frames_dir: The directory to store the frames.
|
149
|
+
- plot_current_time: Whether to plot the current time in the
|
150
|
+
Gantt chart.
|
151
|
+
video_config:
|
152
|
+
Configuration for creating the video. Defaults to ``None``.
|
153
|
+
Valid keys are:
|
154
|
+
|
155
|
+
- video_path: The path to save the video.
|
156
|
+
- fps: The frames per second of the video.
|
157
|
+
- remove_frames: Whether to remove the frames after creating
|
158
|
+
the video.
|
159
|
+
- frames_dir: The directory to store the frames.
|
160
|
+
- plot_current_time: Whether to plot the current time in the
|
161
|
+
Gantt chart.
|
85
162
|
"""
|
86
163
|
|
87
164
|
def __init__(
|
88
165
|
self,
|
89
166
|
dispatcher: Dispatcher,
|
90
|
-
|
167
|
+
partial_gantt_chart_plotter_config: (
|
168
|
+
PartialGanttChartPlotterConfig | None
|
169
|
+
) = None,
|
91
170
|
gif_config: GifConfig | None = None,
|
92
171
|
video_config: VideoConfig | None = None,
|
93
172
|
):
|
94
|
-
"""Initializes the GanttChartCreator with the given configurations
|
95
|
-
and history observer.
|
96
|
-
|
97
|
-
This class adds a new `HistoryObserver` to the dispatcher if it does
|
98
|
-
not have one already. Otherwise, it uses the observer already present.
|
99
|
-
|
100
|
-
Args:
|
101
|
-
dispatcher:
|
102
|
-
The `Dispatcher` class that will be tracked using a
|
103
|
-
`HistoryObserver`.
|
104
|
-
gantt_chart_wrapper_config:
|
105
|
-
Configuration for the Gantt chart wrapper function. Valid keys
|
106
|
-
are:
|
107
|
-
- title: The title of the Gantt chart.
|
108
|
-
- cmap: The name of the colormap to use.
|
109
|
-
- show_available_operations: Whether to show available
|
110
|
-
operations in each step.
|
111
|
-
|
112
|
-
If `title` or `cmap` are not provided here and
|
113
|
-
`infer_gantt_chart_config` is set to True, the values from
|
114
|
-
`gantt_chart_config` will be used if they are present.
|
115
|
-
gif_config:
|
116
|
-
Configuration for creating the GIF. Defaults to None.
|
117
|
-
Valid keys are:
|
118
|
-
- gif_path: The path to save the GIF.
|
119
|
-
- fps: The frames per second of the GIF.
|
120
|
-
- remove_frames: Whether to remove the frames after creating
|
121
|
-
the GIF.
|
122
|
-
- frames_dir: The directory to store the frames.
|
123
|
-
- plot_current_time: Whether to plot the current time in the
|
124
|
-
Gantt chart.
|
125
|
-
video_config:
|
126
|
-
Configuration for creating the video. Defaults to None.
|
127
|
-
Valid keys are:
|
128
|
-
- video_path: The path to save the video.
|
129
|
-
- fps: The frames per second of the video.
|
130
|
-
- remove_frames: Whether to remove the frames after creating
|
131
|
-
the video.
|
132
|
-
- frames_dir: The directory to store the frames.
|
133
|
-
- plot_current_time: Whether to plot the current time in the
|
134
|
-
Gantt chart.
|
135
|
-
"""
|
136
173
|
if gif_config is None:
|
137
|
-
gif_config = {
|
138
|
-
if
|
139
|
-
|
174
|
+
gif_config = {}
|
175
|
+
if partial_gantt_chart_plotter_config is None:
|
176
|
+
partial_gantt_chart_plotter_config = {}
|
140
177
|
if video_config is None:
|
141
178
|
video_config = {}
|
142
179
|
|
143
180
|
self.gif_config = gif_config
|
144
|
-
self.gannt_chart_wrapper_config =
|
181
|
+
self.gannt_chart_wrapper_config = partial_gantt_chart_plotter_config
|
145
182
|
self.video_config = video_config
|
146
183
|
self.history_observer: HistoryObserver = (
|
147
184
|
dispatcher.create_or_get_observer(HistoryObserver)
|
148
185
|
)
|
149
|
-
self.
|
186
|
+
self.partial_gantt_chart_plotter = get_partial_gantt_chart_plotter(
|
150
187
|
**self.gannt_chart_wrapper_config
|
151
188
|
)
|
152
189
|
|
@@ -169,37 +206,38 @@ class GanttChartCreator:
|
|
169
206
|
"""Plots the current Gantt chart of the schedule.
|
170
207
|
|
171
208
|
Returns:
|
172
|
-
|
173
|
-
The figure and axes of the plotted Gantt chart.
|
209
|
+
The figure of the plotted Gantt chart.
|
174
210
|
"""
|
175
|
-
|
211
|
+
a = self.partial_gantt_chart_plotter(
|
176
212
|
self.schedule,
|
177
213
|
None,
|
178
|
-
self.dispatcher.
|
214
|
+
self.dispatcher.available_operations(),
|
179
215
|
self.dispatcher.current_time(),
|
180
216
|
)
|
217
|
+
return a
|
181
218
|
|
182
219
|
def create_gif(self) -> None:
|
183
220
|
"""Creates a GIF of the schedule being built using the recorded
|
184
221
|
history.
|
185
222
|
|
186
223
|
This method uses the history of scheduled operations recorded by the
|
187
|
-
|
188
|
-
scheduling process.
|
224
|
+
:class:`HistoryTracker` to create a GIF that shows the progression of
|
225
|
+
the scheduling process.
|
189
226
|
|
190
227
|
The GIF creation process involves:
|
228
|
+
|
191
229
|
- Using the history of scheduled operations to generate frames for
|
192
230
|
each step of the schedule.
|
193
231
|
- Creating a GIF from these frames.
|
194
232
|
- Optionally, removing the frames after the GIF is created.
|
195
233
|
|
196
234
|
The configuration for the GIF creation can be customized through the
|
197
|
-
|
235
|
+
``gif_config`` attribute.
|
198
236
|
"""
|
199
|
-
|
237
|
+
create_gantt_chart_gif(
|
200
238
|
instance=self.history_observer.dispatcher.instance,
|
201
239
|
schedule_history=self.history_observer.history,
|
202
|
-
plot_function=self.
|
240
|
+
plot_function=self.partial_gantt_chart_plotter,
|
203
241
|
**self.gif_config
|
204
242
|
)
|
205
243
|
|
@@ -208,12 +246,12 @@ class GanttChartCreator:
|
|
208
246
|
history.
|
209
247
|
|
210
248
|
This method uses the history of scheduled operations recorded by the
|
211
|
-
|
212
|
-
scheduling process.
|
249
|
+
:class:`HistoryTracker` to create a video that shows the progression
|
250
|
+
of the scheduling process.
|
213
251
|
"""
|
214
252
|
create_gantt_chart_video(
|
215
253
|
instance=self.history_observer.dispatcher.instance,
|
216
254
|
schedule_history=self.history_observer.history,
|
217
|
-
plot_function=self.
|
255
|
+
plot_function=self.partial_gantt_chart_plotter,
|
218
256
|
**self.video_config
|
219
257
|
)
|
@@ -3,8 +3,7 @@
|
|
3
3
|
import os
|
4
4
|
import pathlib
|
5
5
|
import shutil
|
6
|
-
from
|
7
|
-
from typing import Sequence
|
6
|
+
from typing import Sequence, Protocol
|
8
7
|
|
9
8
|
import imageio
|
10
9
|
import matplotlib.pyplot as plt
|
@@ -23,19 +22,53 @@ from job_shop_lib.dispatching import (
|
|
23
22
|
HistoryObserver,
|
24
23
|
)
|
25
24
|
from job_shop_lib.dispatching.rules import DispatchingRuleSolver
|
26
|
-
from job_shop_lib.visualization.
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
]
|
32
|
-
|
25
|
+
from job_shop_lib.visualization._plot_gantt_chart import plot_gantt_chart
|
26
|
+
|
27
|
+
|
28
|
+
# This class serves as a more meaningful type hint than simply:
|
29
|
+
# PlotFunction = Callable[
|
30
|
+
# [Schedule, int | None, list[Operation] | None, int | None], Figure
|
31
|
+
# ]
|
32
|
+
# That's why it doesn't have more methods or attributes. It is a protocol
|
33
|
+
# for functions, not for classes.
|
34
|
+
# pylint: disable=too-few-public-methods
|
35
|
+
class PartialGanttChartPlotter(Protocol):
|
36
|
+
"""A protocol for a function that plots an uncompleted Gantt chart
|
37
|
+
for a schedule.
|
38
|
+
|
39
|
+
This kind of functions are created using the
|
40
|
+
:func:`plot_gantt_chart_wrapper` function.
|
41
|
+
"""
|
33
42
|
|
34
|
-
def
|
43
|
+
def __call__(
|
44
|
+
self,
|
45
|
+
schedule: Schedule,
|
46
|
+
makespan: int | None = None,
|
47
|
+
available_operations: list[Operation] | None = None,
|
48
|
+
current_time: int | None = None,
|
49
|
+
) -> Figure:
|
50
|
+
"""Plots a Gantt chart for an unfinished schedule.
|
51
|
+
|
52
|
+
Args:
|
53
|
+
schedule:
|
54
|
+
The schedule to plot.
|
55
|
+
makespan:
|
56
|
+
The makespan of the schedule if known. Can be used to fix
|
57
|
+
the x-axis limits.
|
58
|
+
available_operations:
|
59
|
+
A list of available operations. If ``None``,
|
60
|
+
the available operations are not shown.
|
61
|
+
current_time:
|
62
|
+
The current time in the schedule. If provided, a red
|
63
|
+
vertical line is plotted at this time.
|
64
|
+
"""
|
65
|
+
|
66
|
+
|
67
|
+
def get_partial_gantt_chart_plotter(
|
35
68
|
title: str | None = None,
|
36
69
|
cmap: str = "viridis",
|
37
70
|
show_available_operations: bool = False,
|
38
|
-
) ->
|
71
|
+
) -> PartialGanttChartPlotter:
|
39
72
|
"""Returns a function that plots a Gantt chart for an unfinished schedule.
|
40
73
|
|
41
74
|
Args:
|
@@ -47,12 +80,13 @@ def plot_gantt_chart_wrapper(
|
|
47
80
|
Returns:
|
48
81
|
A function that plots a Gantt chart for a schedule. The function takes
|
49
82
|
the following arguments:
|
83
|
+
|
50
84
|
- schedule: The schedule to plot.
|
51
85
|
- makespan: The makespan of the schedule.
|
52
86
|
- available_operations: A list of available operations. If None,
|
53
|
-
|
87
|
+
the available operations are not shown.
|
54
88
|
- current_time: The current time in the schedule. If provided, a
|
55
|
-
|
89
|
+
red vertical line is plotted at this time.
|
56
90
|
|
57
91
|
"""
|
58
92
|
|
@@ -97,33 +131,30 @@ def plot_gantt_chart_wrapper(
|
|
97
131
|
# Most of the arguments are optional with default values. There is no way to
|
98
132
|
# reduce the number of arguments without losing functionality.
|
99
133
|
# pylint: disable=too-many-arguments
|
100
|
-
def
|
101
|
-
gif_path: str | None,
|
134
|
+
def create_gantt_chart_gif(
|
102
135
|
instance: JobShopInstance,
|
136
|
+
gif_path: str | None = None,
|
103
137
|
solver: DispatchingRuleSolver | None = None,
|
104
|
-
plot_function:
|
138
|
+
plot_function: PartialGanttChartPlotter | None = None,
|
105
139
|
fps: int = 1,
|
106
140
|
remove_frames: bool = True,
|
107
141
|
frames_dir: str | None = None,
|
108
142
|
plot_current_time: bool = True,
|
109
143
|
schedule_history: Sequence[ScheduledOperation] | None = None,
|
110
144
|
) -> None:
|
111
|
-
"""Creates a GIF of the schedule being built
|
112
|
-
|
113
|
-
Deprecated since version 0.6.0: Use `create_gif_or_video` instead.
|
145
|
+
"""Creates a GIF of the schedule being built.
|
114
146
|
|
115
147
|
Args:
|
116
|
-
gif_path:
|
117
|
-
The path to save the GIF file. It should end with ".gif". If not
|
118
|
-
provided, the name of the instance is used. It will be made an
|
119
|
-
optional argument in version 1.0.0.
|
120
148
|
instance:
|
121
149
|
The instance of the job shop problem to be scheduled.
|
150
|
+
gif_path:
|
151
|
+
The path to save the GIF file. It should end with ".gif". If not
|
152
|
+
provided, the name of the instance is used.
|
122
153
|
solver:
|
123
154
|
The dispatching rule solver to use. If not provided, the history
|
124
155
|
of scheduled operations should be provided.
|
125
156
|
plot_function:
|
126
|
-
A
|
157
|
+
A :class:`PlotFunction` that plots a Gantt chart for a schedule. It
|
127
158
|
should take a `Schedule` object and the makespan of the schedule as
|
128
159
|
input and return a `Figure` object. If not provided, a default
|
129
160
|
function is used.
|
@@ -133,7 +164,7 @@ def create_gif(
|
|
133
164
|
Whether to remove the frames after creating the GIF.
|
134
165
|
frames_dir:
|
135
166
|
The directory to save the frames in. If not provided,
|
136
|
-
|
167
|
+
``gif_path.replace(".gif", "") + "_frames"`` is used.
|
137
168
|
plot_current_time:
|
138
169
|
Whether to plot a vertical line at the current time.
|
139
170
|
schedule_history:
|
@@ -144,7 +175,7 @@ def create_gif(
|
|
144
175
|
gif_path = f"{instance.name}_gantt_chart.gif"
|
145
176
|
|
146
177
|
if plot_function is None:
|
147
|
-
plot_function =
|
178
|
+
plot_function = get_partial_gantt_chart_plotter()
|
148
179
|
|
149
180
|
if frames_dir is None:
|
150
181
|
# Use the name of the GIF file as the directory name
|
@@ -173,14 +204,14 @@ def create_gantt_chart_video(
|
|
173
204
|
instance: JobShopInstance,
|
174
205
|
video_path: str | None = None,
|
175
206
|
solver: DispatchingRuleSolver | None = None,
|
176
|
-
plot_function:
|
207
|
+
plot_function: PartialGanttChartPlotter | None = None,
|
177
208
|
fps: int = 1,
|
178
209
|
remove_frames: bool = True,
|
179
210
|
frames_dir: str | None = None,
|
180
211
|
plot_current_time: bool = True,
|
181
212
|
schedule_history: Sequence[ScheduledOperation] | None = None,
|
182
213
|
) -> None:
|
183
|
-
"""Creates a
|
214
|
+
"""Creates a video of the schedule being built.
|
184
215
|
|
185
216
|
Args:
|
186
217
|
instance:
|
@@ -192,16 +223,16 @@ def create_gantt_chart_video(
|
|
192
223
|
of scheduled operations should be provided.
|
193
224
|
plot_function:
|
194
225
|
A function that plots a Gantt chart for a schedule. It
|
195
|
-
should take a
|
196
|
-
input and return a
|
197
|
-
function is used.
|
226
|
+
should take a :class:`Schedule` object and the makespan of the
|
227
|
+
schedule as input and return a ``Figure`` object. If not provided,
|
228
|
+
a default function is used.
|
198
229
|
fps:
|
199
|
-
The number of frames per second in the
|
230
|
+
The number of frames per second in the video.
|
200
231
|
remove_frames:
|
201
|
-
Whether to remove the frames after creating the
|
232
|
+
Whether to remove the frames after creating the video.
|
202
233
|
frames_dir:
|
203
234
|
The directory to save the frames in. If not provided,
|
204
|
-
|
235
|
+
``name_without_the_extension + "_frames"`` is used.
|
205
236
|
plot_current_time:
|
206
237
|
Whether to plot a vertical line at the current time.
|
207
238
|
schedule_history:
|
@@ -212,7 +243,7 @@ def create_gantt_chart_video(
|
|
212
243
|
video_path = f"{instance.name}_gantt_chart.mp4"
|
213
244
|
|
214
245
|
if plot_function is None:
|
215
|
-
plot_function =
|
246
|
+
plot_function = get_partial_gantt_chart_plotter()
|
216
247
|
|
217
248
|
if frames_dir is None:
|
218
249
|
extension = video_path.split(".")[-1]
|
@@ -238,7 +269,7 @@ def create_gantt_chart_frames(
|
|
238
269
|
frames_dir: str,
|
239
270
|
instance: JobShopInstance,
|
240
271
|
solver: DispatchingRuleSolver | None,
|
241
|
-
plot_function:
|
272
|
+
plot_function: PartialGanttChartPlotter,
|
242
273
|
plot_current_time: bool = True,
|
243
274
|
schedule_history: Sequence[ScheduledOperation] | None = None,
|
244
275
|
) -> None:
|
@@ -295,7 +326,7 @@ def create_gantt_chart_frames(
|
|
295
326
|
fig = plot_function(
|
296
327
|
dispatcher.schedule,
|
297
328
|
makespan,
|
298
|
-
dispatcher.
|
329
|
+
dispatcher.available_operations(),
|
299
330
|
current_time,
|
300
331
|
)
|
301
332
|
_save_frame(fig, frames_dir, i)
|