job-shop-lib 1.0.0a2__py3-none-any.whl → 1.0.0a4__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.
- 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)
|