job-shop-lib 0.5.0__py3-none-any.whl → 1.0.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.
Files changed (93) hide show
  1. job_shop_lib/__init__.py +19 -8
  2. job_shop_lib/{base_solver.py → _base_solver.py} +1 -1
  3. job_shop_lib/{job_shop_instance.py → _job_shop_instance.py} +155 -81
  4. job_shop_lib/_operation.py +118 -0
  5. job_shop_lib/{schedule.py → _schedule.py} +102 -84
  6. job_shop_lib/{scheduled_operation.py → _scheduled_operation.py} +25 -49
  7. job_shop_lib/benchmarking/__init__.py +66 -43
  8. job_shop_lib/benchmarking/_load_benchmark.py +88 -0
  9. job_shop_lib/constraint_programming/__init__.py +13 -0
  10. job_shop_lib/{cp_sat/ortools_solver.py → constraint_programming/_ortools_solver.py} +77 -22
  11. job_shop_lib/dispatching/__init__.py +51 -42
  12. job_shop_lib/dispatching/{dispatcher.py → _dispatcher.py} +223 -130
  13. job_shop_lib/dispatching/_dispatcher_observer_config.py +67 -0
  14. job_shop_lib/dispatching/_factories.py +135 -0
  15. job_shop_lib/dispatching/{history_tracker.py → _history_observer.py} +6 -7
  16. job_shop_lib/dispatching/_optimal_operations_observer.py +113 -0
  17. job_shop_lib/dispatching/_ready_operation_filters.py +168 -0
  18. job_shop_lib/dispatching/_unscheduled_operations_observer.py +70 -0
  19. job_shop_lib/dispatching/feature_observers/__init__.py +51 -13
  20. job_shop_lib/dispatching/feature_observers/_composite_feature_observer.py +212 -0
  21. job_shop_lib/dispatching/feature_observers/{duration_observer.py → _duration_observer.py} +20 -18
  22. job_shop_lib/dispatching/feature_observers/_earliest_start_time_observer.py +289 -0
  23. job_shop_lib/dispatching/feature_observers/_factory.py +95 -0
  24. job_shop_lib/dispatching/feature_observers/_feature_observer.py +228 -0
  25. job_shop_lib/dispatching/feature_observers/_is_completed_observer.py +97 -0
  26. job_shop_lib/dispatching/feature_observers/_is_ready_observer.py +35 -0
  27. job_shop_lib/dispatching/feature_observers/{is_scheduled_observer.py → _is_scheduled_observer.py} +9 -5
  28. job_shop_lib/dispatching/feature_observers/{position_in_job_observer.py → _position_in_job_observer.py} +8 -10
  29. job_shop_lib/dispatching/feature_observers/{remaining_operations_observer.py → _remaining_operations_observer.py} +8 -26
  30. job_shop_lib/dispatching/rules/__init__.py +87 -0
  31. job_shop_lib/dispatching/rules/_dispatching_rule_factory.py +84 -0
  32. job_shop_lib/dispatching/rules/_dispatching_rule_solver.py +201 -0
  33. job_shop_lib/dispatching/{dispatching_rules.py → rules/_dispatching_rules_functions.py} +70 -16
  34. job_shop_lib/dispatching/rules/_machine_chooser_factory.py +71 -0
  35. job_shop_lib/dispatching/rules/_utils.py +128 -0
  36. job_shop_lib/exceptions.py +18 -0
  37. job_shop_lib/generation/__init__.py +19 -0
  38. job_shop_lib/generation/_general_instance_generator.py +165 -0
  39. job_shop_lib/generation/_instance_generator.py +133 -0
  40. job_shop_lib/{generators/transformations.py → generation/_transformations.py} +16 -12
  41. job_shop_lib/generation/_utils.py +124 -0
  42. job_shop_lib/graphs/__init__.py +30 -12
  43. job_shop_lib/graphs/{build_disjunctive_graph.py → _build_disjunctive_graph.py} +41 -3
  44. job_shop_lib/graphs/{build_agent_task_graph.py → _build_resource_task_graphs.py} +28 -26
  45. job_shop_lib/graphs/_constants.py +38 -0
  46. job_shop_lib/graphs/_job_shop_graph.py +320 -0
  47. job_shop_lib/graphs/_node.py +182 -0
  48. job_shop_lib/graphs/graph_updaters/__init__.py +26 -0
  49. job_shop_lib/graphs/graph_updaters/_disjunctive_graph_updater.py +108 -0
  50. job_shop_lib/graphs/graph_updaters/_graph_updater.py +57 -0
  51. job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py +155 -0
  52. job_shop_lib/graphs/graph_updaters/_utils.py +25 -0
  53. job_shop_lib/py.typed +0 -0
  54. job_shop_lib/reinforcement_learning/__init__.py +68 -0
  55. job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py +398 -0
  56. job_shop_lib/reinforcement_learning/_resource_task_graph_observation.py +329 -0
  57. job_shop_lib/reinforcement_learning/_reward_observers.py +87 -0
  58. job_shop_lib/reinforcement_learning/_single_job_shop_graph_env.py +443 -0
  59. job_shop_lib/reinforcement_learning/_types_and_constants.py +62 -0
  60. job_shop_lib/reinforcement_learning/_utils.py +199 -0
  61. job_shop_lib/visualization/__init__.py +0 -25
  62. job_shop_lib/visualization/gantt/__init__.py +48 -0
  63. job_shop_lib/visualization/gantt/_gantt_chart_creator.py +257 -0
  64. job_shop_lib/visualization/gantt/_gantt_chart_video_and_gif_creation.py +422 -0
  65. job_shop_lib/visualization/{gantt_chart.py → gantt/_plot_gantt_chart.py} +84 -21
  66. job_shop_lib/visualization/graphs/__init__.py +29 -0
  67. job_shop_lib/visualization/graphs/_plot_disjunctive_graph.py +418 -0
  68. job_shop_lib/visualization/graphs/_plot_resource_task_graph.py +389 -0
  69. {job_shop_lib-0.5.0.dist-info → job_shop_lib-1.0.0.dist-info}/METADATA +87 -55
  70. job_shop_lib-1.0.0.dist-info/RECORD +73 -0
  71. {job_shop_lib-0.5.0.dist-info → job_shop_lib-1.0.0.dist-info}/WHEEL +1 -1
  72. job_shop_lib/benchmarking/load_benchmark.py +0 -142
  73. job_shop_lib/cp_sat/__init__.py +0 -5
  74. job_shop_lib/dispatching/dispatching_rule_solver.py +0 -119
  75. job_shop_lib/dispatching/factories.py +0 -206
  76. job_shop_lib/dispatching/feature_observers/composite_feature_observer.py +0 -87
  77. job_shop_lib/dispatching/feature_observers/earliest_start_time_observer.py +0 -156
  78. job_shop_lib/dispatching/feature_observers/factory.py +0 -58
  79. job_shop_lib/dispatching/feature_observers/feature_observer.py +0 -113
  80. job_shop_lib/dispatching/feature_observers/is_completed_observer.py +0 -98
  81. job_shop_lib/dispatching/feature_observers/is_ready_observer.py +0 -40
  82. job_shop_lib/dispatching/pruning_functions.py +0 -116
  83. job_shop_lib/generators/__init__.py +0 -7
  84. job_shop_lib/generators/basic_generator.py +0 -197
  85. job_shop_lib/graphs/constants.py +0 -21
  86. job_shop_lib/graphs/job_shop_graph.py +0 -202
  87. job_shop_lib/graphs/node.py +0 -166
  88. job_shop_lib/operation.py +0 -122
  89. job_shop_lib/visualization/agent_task_graph.py +0 -257
  90. job_shop_lib/visualization/create_gif.py +0 -209
  91. job_shop_lib/visualization/disjunctive_graph.py +0 -210
  92. job_shop_lib-0.5.0.dist-info/RECORD +0 -48
  93. {job_shop_lib-0.5.0.dist-info → job_shop_lib-1.0.0.dist-info}/LICENSE +0 -0
@@ -1,25 +0,0 @@
1
- """Package for visualization."""
2
-
3
- from job_shop_lib.visualization.gantt_chart import plot_gantt_chart
4
- from job_shop_lib.visualization.create_gif import (
5
- create_gif,
6
- create_gantt_chart_frames,
7
- plot_gantt_chart_wrapper,
8
- create_gif_from_frames,
9
- )
10
- from job_shop_lib.visualization.disjunctive_graph import plot_disjunctive_graph
11
- from job_shop_lib.visualization.agent_task_graph import (
12
- plot_agent_task_graph,
13
- three_columns_layout,
14
- )
15
-
16
- __all__ = [
17
- "plot_gantt_chart",
18
- "create_gif",
19
- "create_gantt_chart_frames",
20
- "plot_gantt_chart_wrapper",
21
- "create_gif_from_frames",
22
- "plot_disjunctive_graph",
23
- "plot_agent_task_graph",
24
- "three_columns_layout",
25
- ]
@@ -0,0 +1,48 @@
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
+ GanttChartCreator
11
+ GifConfig
12
+ VideoConfig
13
+ PartialGanttChartPlotterConfig
14
+
15
+ """
16
+
17
+ from ._plot_gantt_chart import plot_gantt_chart
18
+ from ._gantt_chart_video_and_gif_creation import (
19
+ create_gantt_chart_gif,
20
+ create_gantt_chart_video,
21
+ create_gantt_chart_frames,
22
+ get_partial_gantt_chart_plotter,
23
+ create_video_from_frames,
24
+ create_gif_from_frames,
25
+ PartialGanttChartPlotter,
26
+ )
27
+
28
+ from ._gantt_chart_creator import (
29
+ GanttChartCreator,
30
+ PartialGanttChartPlotterConfig,
31
+ GifConfig,
32
+ VideoConfig,
33
+ )
34
+
35
+ __all__ = [
36
+ "plot_gantt_chart",
37
+ "create_gantt_chart_video",
38
+ "create_gantt_chart_gif",
39
+ "create_gantt_chart_frames",
40
+ "get_partial_gantt_chart_plotter",
41
+ "create_gif_from_frames",
42
+ "create_video_from_frames",
43
+ "GanttChartCreator",
44
+ "PartialGanttChartPlotterConfig",
45
+ "GifConfig",
46
+ "VideoConfig",
47
+ "PartialGanttChartPlotter",
48
+ ]
@@ -0,0 +1,257 @@
1
+ """Home of the `GanttChartCreator` class and its configuration types."""
2
+
3
+ from typing import TypedDict, Optional
4
+ import matplotlib.pyplot as plt
5
+
6
+ from job_shop_lib.dispatching import (
7
+ Dispatcher,
8
+ HistoryObserver,
9
+ )
10
+ from job_shop_lib.visualization.gantt import (
11
+ create_gantt_chart_video,
12
+ get_partial_gantt_chart_plotter,
13
+ create_gantt_chart_gif,
14
+ )
15
+
16
+
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
+ """
26
+
27
+ title: Optional[str]
28
+ """The title of the Gantt chart."""
29
+
30
+ cmap: str
31
+ """The colormap to use in the Gantt chart."""
32
+
33
+ show_available_operations: bool
34
+ """Whether to show available operations in each step."""
35
+
36
+
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.
40
+
41
+ .. seealso::
42
+
43
+ :func:`create_gantt_chart_gif`
44
+ """
45
+
46
+ gif_path: Optional[str]
47
+ """The path to save the GIF. It must end with '.gif'."""
48
+
49
+ fps: int
50
+ """The frames per second of the GIF. Defaults to 1."""
51
+
52
+ remove_frames: bool
53
+ """Whether to remove the frames after creating the GIF."""
54
+
55
+ frames_dir: Optional[str]
56
+ """The directory to store the frames."""
57
+
58
+ plot_current_time: bool
59
+ """Whether to plot the current time in the Gantt chart."""
60
+
61
+
62
+ class VideoConfig(TypedDict, total=False):
63
+ """Configuration for creating the video using the
64
+ :func:`create_gantt_chart_video` function.
65
+
66
+ .. seealso::
67
+
68
+ :func:`create_gantt_chart_video`
69
+ """
70
+
71
+ video_path: Optional[str]
72
+ """The path to save the video. It must end with a valid video extension
73
+ (e.g., '.mp4')."""
74
+
75
+ fps: int
76
+ """The frames per second of the video. Defaults to 1."""
77
+
78
+ remove_frames: bool
79
+ """Whether to remove the frames after creating the video."""
80
+
81
+ frames_dir: Optional[str]
82
+ """The directory to store the frames."""
83
+
84
+ plot_current_time: bool
85
+ """Whether to plot the current time in the Gantt chart."""
86
+
87
+
88
+ class GanttChartCreator:
89
+ """Facade class that centralizes the creation of Gantt charts, videos
90
+ and GIFs.
91
+
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.
96
+
97
+ It adds a new :class:`HistoryObserver` to the dispatcher if it does
98
+ not have one already. Otherwise, it uses the observer already present.
99
+
100
+ Attributes:
101
+ history_observer:
102
+ The history observer observing the dispatcher's state.
103
+ gantt_chart_config:
104
+ Configuration for plotting the Gantt chart.
105
+ gif_config:
106
+ Configuration for creating the GIF.
107
+ gantt_chart_wrapper_config:
108
+ Configuration for the Gantt chart wrapper function.
109
+ video_config:
110
+ Configuration for creating the video.
111
+ plot_function:
112
+ The function used to plot the Gantt chart when creating the GIF
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.
162
+ """
163
+
164
+ def __init__(
165
+ self,
166
+ dispatcher: Dispatcher,
167
+ partial_gantt_chart_plotter_config: Optional[
168
+ PartialGanttChartPlotterConfig
169
+ ] = None,
170
+ gif_config: Optional[GifConfig] = None,
171
+ video_config: Optional[VideoConfig] = None,
172
+ ):
173
+ if gif_config is None:
174
+ gif_config = {}
175
+ if partial_gantt_chart_plotter_config is None:
176
+ partial_gantt_chart_plotter_config = {}
177
+ if video_config is None:
178
+ video_config = {}
179
+
180
+ self.gif_config = gif_config
181
+ self.gannt_chart_wrapper_config = partial_gantt_chart_plotter_config
182
+ self.video_config = video_config
183
+ self.history_observer: HistoryObserver = (
184
+ dispatcher.create_or_get_observer(HistoryObserver)
185
+ )
186
+ self.partial_gantt_chart_plotter = get_partial_gantt_chart_plotter(
187
+ **self.gannt_chart_wrapper_config
188
+ )
189
+
190
+ @property
191
+ def instance(self):
192
+ """The instance being scheduled."""
193
+ return self.history_observer.dispatcher.instance
194
+
195
+ @property
196
+ def schedule(self):
197
+ """The current schedule."""
198
+ return self.history_observer.dispatcher.schedule
199
+
200
+ @property
201
+ def dispatcher(self):
202
+ """The dispatcher being observed."""
203
+ return self.history_observer.dispatcher
204
+
205
+ def plot_gantt_chart(self) -> plt.Figure:
206
+ """Plots the current Gantt chart of the schedule.
207
+
208
+ Returns:
209
+ The figure of the plotted Gantt chart.
210
+ """
211
+ a = self.partial_gantt_chart_plotter(
212
+ self.schedule,
213
+ None,
214
+ self.dispatcher.available_operations(),
215
+ self.dispatcher.current_time(),
216
+ )
217
+ return a
218
+
219
+ def create_gif(self) -> None:
220
+ """Creates a GIF of the schedule being built using the recorded
221
+ history.
222
+
223
+ This method uses the history of scheduled operations recorded by the
224
+ :class:`HistoryTracker` to create a GIF that shows the progression of
225
+ the scheduling process.
226
+
227
+ The GIF creation process involves:
228
+
229
+ - Using the history of scheduled operations to generate frames for
230
+ each step of the schedule.
231
+ - Creating a GIF from these frames.
232
+ - Optionally, removing the frames after the GIF is created.
233
+
234
+ The configuration for the GIF creation can be customized through the
235
+ ``gif_config`` attribute.
236
+ """
237
+ create_gantt_chart_gif(
238
+ instance=self.history_observer.dispatcher.instance,
239
+ schedule_history=self.history_observer.history,
240
+ plot_function=self.partial_gantt_chart_plotter,
241
+ **self.gif_config
242
+ )
243
+
244
+ def create_video(self) -> None:
245
+ """Creates a video of the schedule being built using the recorded
246
+ history.
247
+
248
+ This method uses the history of scheduled operations recorded by the
249
+ :class:`HistoryTracker` to create a video that shows the progression
250
+ of the scheduling process.
251
+ """
252
+ create_gantt_chart_video(
253
+ instance=self.history_observer.dispatcher.instance,
254
+ schedule_history=self.history_observer.history,
255
+ plot_function=self.partial_gantt_chart_plotter,
256
+ **self.video_config
257
+ )