job-shop-lib 1.0.0a3__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.
Files changed (32) hide show
  1. job_shop_lib/_job_shop_instance.py +104 -38
  2. job_shop_lib/_operation.py +12 -3
  3. job_shop_lib/_schedule.py +10 -12
  4. job_shop_lib/_scheduled_operation.py +15 -16
  5. job_shop_lib/dispatching/_dispatcher.py +12 -15
  6. job_shop_lib/dispatching/_dispatcher_observer_config.py +15 -2
  7. job_shop_lib/dispatching/_factories.py +2 -2
  8. job_shop_lib/dispatching/feature_observers/_composite_feature_observer.py +0 -1
  9. job_shop_lib/dispatching/feature_observers/_factory.py +21 -18
  10. job_shop_lib/dispatching/feature_observers/_is_completed_observer.py +1 -0
  11. job_shop_lib/dispatching/rules/_dispatching_rule_solver.py +1 -1
  12. job_shop_lib/generation/_general_instance_generator.py +33 -34
  13. job_shop_lib/generation/_instance_generator.py +14 -17
  14. job_shop_lib/generation/_transformations.py +11 -8
  15. job_shop_lib/graphs/__init__.py +3 -0
  16. job_shop_lib/graphs/_build_disjunctive_graph.py +41 -3
  17. job_shop_lib/graphs/graph_updaters/_graph_updater.py +11 -13
  18. job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py +17 -20
  19. job_shop_lib/reinforcement_learning/__init__.py +16 -7
  20. job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py +69 -57
  21. job_shop_lib/reinforcement_learning/_single_job_shop_graph_env.py +42 -31
  22. job_shop_lib/reinforcement_learning/_types_and_constants.py +2 -2
  23. job_shop_lib/visualization/__init__.py +24 -5
  24. job_shop_lib/visualization/_gantt_chart_creator.py +118 -80
  25. job_shop_lib/visualization/_gantt_chart_video_and_gif_creation.py +15 -11
  26. job_shop_lib/visualization/_plot_disjunctive_graph.py +382 -0
  27. {job_shop_lib-1.0.0a3.dist-info → job_shop_lib-1.0.0a4.dist-info}/METADATA +5 -5
  28. {job_shop_lib-1.0.0a3.dist-info → job_shop_lib-1.0.0a4.dist-info}/RECORD +31 -31
  29. job_shop_lib/visualization/_disjunctive_graph.py +0 -210
  30. /job_shop_lib/visualization/{_agent_task_graph.py → _plot_agent_task_graph.py} +0 -0
  31. {job_shop_lib-1.0.0a3.dist-info → job_shop_lib-1.0.0a4.dist-info}/LICENSE +0 -0
  32. {job_shop_lib-1.0.0a3.dist-info → job_shop_lib-1.0.0a4.dist-info}/WHEEL +0 -0
@@ -45,6 +45,7 @@ class SingleJobShopGraphEnv(gym.Env):
45
45
 
46
46
  Observation Space:
47
47
  A dictionary with the following keys:
48
+
48
49
  - "removed_nodes": Binary vector indicating removed graph nodes.
49
50
  - "edge_list": Matrix of graph edges in COO format.
50
51
  - Feature matrices: Keys corresponding to the composite observer
@@ -54,43 +55,76 @@ class SingleJobShopGraphEnv(gym.Env):
54
55
  MultiDiscrete space representing (job_id, machine_id) pairs.
55
56
 
56
57
  Render Modes:
57
- - "human": Displays the current Gantt chart.
58
- - "save_video": Saves a video of the complete Gantt chart.
59
- - "save_gif": Saves a GIF of the complete Gantt chart.
58
+
59
+ - "human": Displays the current Gantt chart.
60
+ - "save_video": Saves a video of the complete Gantt chart.
61
+ - "save_gif": Saves a GIF of the complete Gantt chart.
60
62
 
61
63
  Attributes:
62
64
  dispatcher:
63
65
  Manages the scheduling process. See
64
66
  :class:`~job_shop_lib.dispatching.Dispatcher`.
67
+
65
68
  composite_observer:
66
69
  A :class:`~job_shop_lib.dispatching.feature_observers.
67
70
  CompositeFeatureObserver` which aggregates features from multiple
68
71
  observers.
72
+
69
73
  graph_updater:
70
74
  Updates the graph representation after each action. See
71
75
  :class:`~job_shop_lib.graphs.GraphUpdater`.
76
+
72
77
  reward_function:
73
78
  Computes rewards for actions taken. See
74
79
  :class:`~job_shop_lib.reinforcement_learning.RewardObserver`.
80
+
75
81
  action_space:
76
82
  Defines the action space. The action is a tuple of two integers
77
83
  (job_id, machine_id). The machine_id can be -1 if the selected
78
84
  operation can only be scheduled in one machine.
85
+
79
86
  observation_space:
80
87
  Defines the observation space. The observation is a dictionary
81
88
  with the following keys:
89
+
82
90
  - "removed_nodes": Binary vector indicating removed graph nodes.
83
91
  - "edge_list": Matrix of graph edges in COO format.
84
92
  - Feature matrices: Keys corresponding to the composite observer
85
93
  features (e.g., "operations", "jobs", "machines").
94
+
86
95
  render_mode:
87
96
  The mode for rendering the environment ("human", "save_video",
88
97
  "save_gif").
98
+
89
99
  gantt_chart_creator:
90
100
  Creates Gantt chart visualizations. See
91
101
  :class:`~job_shop_lib.visualization.GanttChartCreator`.
102
+
92
103
  use_padding:
93
104
  Whether to use padding in observations. Padding maintains the
105
+ observation space shape when the number of nodes changes.
106
+
107
+ Args:
108
+ job_shop_graph:
109
+ The JobShopGraph instance representing the job shop problem.
110
+ feature_observer_configs:
111
+ A list of FeatureObserverConfig instances for the feature
112
+ observers.
113
+ reward_function_config:
114
+ The configuration for the reward function.
115
+ graph_updater_config:
116
+ The configuration for the graph updater.
117
+ ready_operations_filter:
118
+ The function to use for pruning dominated operations.
119
+ render_mode:
120
+ The mode for rendering the environment ("human", "save_video",
121
+ "save_gif").
122
+ render_config:
123
+ Configuration for rendering (e.g., paths for saving videos
124
+ or GIFs). See :class:`~job_shop_lib.visualization.RenderConfig`.
125
+ use_padding:
126
+ Whether to use padding in observations. Padding maintains the
127
+ observation space shape when the number of nodes changes.
94
128
  """
95
129
 
96
130
  metadata = {"render_modes": ["human", "save_video", "save_gif"]}
@@ -116,29 +150,6 @@ class SingleJobShopGraphEnv(gym.Env):
116
150
  render_config: RenderConfig | None = None,
117
151
  use_padding: bool = True,
118
152
  ) -> None:
119
- """Initializes the SingleJobShopGraphEnv environment.
120
-
121
- Args:
122
- job_shop_graph:
123
- The JobShopGraph instance representing the job shop problem.
124
- feature_observer_configs:
125
- A list of FeatureObserverConfig instances for the feature
126
- observers.
127
- reward_function_config:
128
- The configuration for the reward function.
129
- graph_updater_config:
130
- The configuration for the graph updater.
131
- ready_operations_filter:
132
- The function to use for pruning dominated operations.
133
- render_mode:
134
- The mode for rendering the environment ("human", "save_video",
135
- "save_gif").
136
- render_config:
137
- Configuration for rendering (e.g., paths for saving videos
138
- or GIFs).
139
- use_padding:
140
- Whether to use padding for the edge index.
141
- """
142
153
  super().__init__()
143
154
  # Used for resetting the environment
144
155
  self.initial_job_shop_graph = deepcopy(job_shop_graph)
@@ -236,16 +247,16 @@ class SingleJobShopGraphEnv(gym.Env):
236
247
 
237
248
  Returns:
238
249
  A tuple containing the following elements:
250
+
239
251
  - The observation of the environment.
240
252
  - The reward obtained.
241
253
  - Whether the environment is done.
242
254
  - Whether the episode was truncated (always False).
243
255
  - A dictionary with additional information. The dictionary
244
- contains the following keys:
245
- - "feature_names": The names of the features in the
246
- observation.
247
- - "available_operations": The operations that are ready to be
248
- scheduled.
256
+ contains the following keys: "feature_names", the names of the
257
+ features in the observation; "available_operations", the
258
+ operations that are ready to be scheduled.
259
+
249
260
  """
250
261
  job_id, machine_id = action
251
262
  operation = self.dispatcher.next_operation(job_id)
@@ -8,7 +8,7 @@ import numpy as np
8
8
 
9
9
  from job_shop_lib.dispatching.feature_observers import FeatureType
10
10
  from job_shop_lib.visualization import (
11
- GanttChartWrapperConfig,
11
+ PartialGanttChartPlotterConfig,
12
12
  GifConfig,
13
13
  VideoConfig,
14
14
  )
@@ -17,7 +17,7 @@ from job_shop_lib.visualization import (
17
17
  class RenderConfig(TypedDict, total=False):
18
18
  """Configuration needed to initialize the `GanttChartCreator` class."""
19
19
 
20
- gantt_chart_wrapper_config: GanttChartWrapperConfig
20
+ partial_gantt_chart_plotter_config: PartialGanttChartPlotterConfig
21
21
  video_config: VideoConfig
22
22
  gif_config: GifConfig
23
23
 
@@ -1,4 +1,19 @@
1
- """Package for visualization."""
1
+ """Contains functions and classes for visualizing job shop scheduling problems.
2
+
3
+ .. autosummary::
4
+
5
+ plot_gantt_chart
6
+ get_partial_gantt_chart_plotter
7
+ PartialGanttChartPlotter
8
+ create_gantt_chart_video
9
+ create_gantt_chart_gif
10
+ plot_disjunctive_graph
11
+ plot_agent_task_graph
12
+ GanttChartCreator
13
+ GifConfig
14
+ VideoConfig
15
+
16
+ """
2
17
 
3
18
  from job_shop_lib.visualization._plot_gantt_chart import plot_gantt_chart
4
19
  from job_shop_lib.visualization._gantt_chart_video_and_gif_creation import (
@@ -8,17 +23,19 @@ from job_shop_lib.visualization._gantt_chart_video_and_gif_creation import (
8
23
  get_partial_gantt_chart_plotter,
9
24
  create_video_from_frames,
10
25
  create_gif_from_frames,
26
+ PartialGanttChartPlotter,
11
27
  )
12
- from job_shop_lib.visualization._disjunctive_graph import (
28
+ from job_shop_lib.visualization._plot_disjunctive_graph import (
13
29
  plot_disjunctive_graph,
30
+ duration_labeler,
14
31
  )
15
- from job_shop_lib.visualization._agent_task_graph import (
32
+ from job_shop_lib.visualization._plot_agent_task_graph import (
16
33
  plot_agent_task_graph,
17
34
  three_columns_layout,
18
35
  )
19
36
  from job_shop_lib.visualization._gantt_chart_creator import (
20
37
  GanttChartCreator,
21
- GanttChartWrapperConfig,
38
+ PartialGanttChartPlotterConfig,
22
39
  GifConfig,
23
40
  VideoConfig,
24
41
  )
@@ -35,7 +52,9 @@ __all__ = [
35
52
  "plot_agent_task_graph",
36
53
  "three_columns_layout",
37
54
  "GanttChartCreator",
38
- "GanttChartWrapperConfig",
55
+ "PartialGanttChartPlotterConfig",
39
56
  "GifConfig",
40
57
  "VideoConfig",
58
+ "PartialGanttChartPlotter",
59
+ "duration_labeler",
41
60
  ]
@@ -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 (
@@ -15,57 +14,87 @@ from job_shop_lib.visualization import (
15
14
  )
16
15
 
17
16
 
18
- class GanttChartWrapperConfig(TypedDict, total=False):
19
- """Configuration for creating the plot function with the
20
- `plot_gantt_chart_wrapper` function."""
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
- # We can't use Required here because it's not available in Python 3.10
28
- class _GifConfigRequired(TypedDict):
29
- """Required configuration for creating the GIF."""
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
- gif_path: str | None
41
+ .. seealso::
32
42
 
43
+ :func:`create_gantt_chart_gif`
44
+ """
33
45
 
34
- class _GifConfigOptional(TypedDict, total=False):
35
- """Optional configuration for creating the GIF."""
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
- frames_dir: str | None
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
- class GifConfig(_GifConfigRequired, _GifConfigOptional):
44
- """Configuration for creating the GIF using the `create_gannt_chart_video`
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
- `create_gannt_chart_video` function."""
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 `HistoryObserver` to keep track of the operations being
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 the
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 `HistoryObserver` to the dispatcher if it does
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 `plot_gantt_chart_wrapper` function.
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
- gantt_chart_wrapper_config: GanttChartWrapperConfig | None = None,
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 = {"gif_path": None}
138
- if gantt_chart_wrapper_config is None:
139
- gantt_chart_wrapper_config = {}
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 = gantt_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.plot_function = get_partial_gantt_chart_plotter(
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
- tuple[plt.Figure, plt.Axes]:
173
- The figure and axes of the plotted Gantt chart.
209
+ The figure of the plotted Gantt chart.
174
210
  """
175
- return self.plot_function(
211
+ a = self.partial_gantt_chart_plotter(
176
212
  self.schedule,
177
213
  None,
178
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
- `HistoryTracker` to create a GIF that shows the progression of the
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
- `gif_config` attribute.
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.plot_function,
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
- `HistoryTracker` to create a video that shows the progression of the
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.plot_function,
255
+ plot_function=self.partial_gantt_chart_plotter,
218
256
  **self.video_config
219
257
  )
@@ -38,16 +38,6 @@ class PartialGanttChartPlotter(Protocol):
38
38
 
39
39
  This kind of functions are created using the
40
40
  :func:`plot_gantt_chart_wrapper` function.
41
-
42
- The function should take the following arguments:
43
-
44
- - schedule: The schedule to plot.
45
- - makespan: The makespan of the schedule if known. Can be used to fix the
46
- x-axis limits.
47
- - available_operations: A list of available operations. If ``None``,
48
- the available operations are not shown.
49
- - current_time: The current time in the schedule. If provided, a red
50
- vertical line is plotted at this time.
51
41
  """
52
42
 
53
43
  def __call__(
@@ -57,7 +47,21 @@ class PartialGanttChartPlotter(Protocol):
57
47
  available_operations: list[Operation] | None = None,
58
48
  current_time: int | None = None,
59
49
  ) -> Figure:
60
- pass
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
+ """
61
65
 
62
66
 
63
67
  def get_partial_gantt_chart_plotter(