job-shop-lib 1.0.0a3__tar.gz → 1.0.0a5__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/PKG-INFO +14 -14
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/README.md +12 -12
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/__init__.py +3 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/_job_shop_instance.py +104 -38
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/_operation.py +12 -3
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/_schedule.py +10 -12
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/_scheduled_operation.py +15 -16
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/constraint_programming/_ortools_solver.py +2 -1
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/_dispatcher.py +53 -18
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/_dispatcher_observer_config.py +15 -2
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/_factories.py +6 -6
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/_composite_feature_observer.py +0 -1
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/_factory.py +21 -18
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/_is_completed_observer.py +1 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/rules/_dispatching_rule_solver.py +1 -1
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/generation/_general_instance_generator.py +33 -34
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/generation/_instance_generator.py +14 -17
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/generation/_transformations.py +11 -8
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/graphs/__init__.py +3 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/graphs/_build_disjunctive_graph.py +41 -3
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/graphs/graph_updaters/_graph_updater.py +11 -13
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py +17 -20
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/reinforcement_learning/__init__.py +16 -7
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py +69 -57
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/reinforcement_learning/_single_job_shop_graph_env.py +42 -31
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/reinforcement_learning/_types_and_constants.py +2 -2
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/visualization/__init__.py +24 -5
- job_shop_lib-1.0.0a5/job_shop_lib/visualization/_gantt_chart_creator.py +257 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/visualization/_gantt_chart_video_and_gif_creation.py +15 -11
- job_shop_lib-1.0.0a5/job_shop_lib/visualization/_plot_disjunctive_graph.py +382 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/pyproject.toml +9 -2
- job_shop_lib-1.0.0a3/job_shop_lib/visualization/_disjunctive_graph.py +0 -210
- job_shop_lib-1.0.0a3/job_shop_lib/visualization/_gantt_chart_creator.py +0 -219
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/LICENSE +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/_base_solver.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/benchmarking/__init__.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/benchmarking/_load_benchmark.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/benchmarking/benchmark_instances.json +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/constraint_programming/__init__.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/__init__.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/_history_observer.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/_ready_operation_filters.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/_unscheduled_operations_observer.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/__init__.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/_duration_observer.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/_earliest_start_time_observer.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/_feature_observer.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/_is_ready_observer.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/_is_scheduled_observer.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/_position_in_job_observer.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/feature_observers/_remaining_operations_observer.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/rules/__init__.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/rules/_dispatching_rule_factory.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/rules/_dispatching_rules_functions.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/rules/_machine_chooser_factory.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/dispatching/rules/_utils.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/exceptions.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/generation/__init__.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/graphs/_build_agent_task_graph.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/graphs/_constants.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/graphs/_job_shop_graph.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/graphs/_node.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/graphs/graph_updaters/__init__.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/graphs/graph_updaters/_utils.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/reinforcement_learning/_reward_observers.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/reinforcement_learning/_utils.py +0 -0
- /job_shop_lib-1.0.0a3/job_shop_lib/visualization/_agent_task_graph.py → /job_shop_lib-1.0.0a5/job_shop_lib/visualization/_plot_agent_task_graph.py +0 -0
- {job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/visualization/_plot_gantt_chart.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: job-shop-lib
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.0a5
|
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
|
@@ -17,7 +17,7 @@ Requires-Dist: imageio[ffmpeg] (>=2.34.1,<3.0.0)
|
|
17
17
|
Requires-Dist: matplotlib (>=3,<4)
|
18
18
|
Requires-Dist: networkx (>=3,<4)
|
19
19
|
Requires-Dist: numpy (>=1.26.4,<2.0.0)
|
20
|
-
Requires-Dist: ortools (>=9.9,<
|
20
|
+
Requires-Dist: ortools (>=9.9,<10.0)
|
21
21
|
Requires-Dist: pyarrow (>=15.0.0,<16.0.0)
|
22
22
|
Requires-Dist: pygraphviz (>=1.12,<2.0) ; extra == "pygraphviz"
|
23
23
|
Description-Content-Type: text/markdown
|
@@ -40,7 +40,7 @@ JobShopLib is a Python package for creating, solving, and visualizing Job Shop S
|
|
40
40
|
|
41
41
|
It follows a modular design, allowing users to easily extend the library with new solvers, dispatching rules, visualization functions, etc.
|
42
42
|
|
43
|
-
See the [documentation](https://job-shop-lib.readthedocs.io/en/latest/) for more details about the latest version
|
43
|
+
See the [documentation](https://job-shop-lib.readthedocs.io/en/latest/) for more details about the latest version.
|
44
44
|
|
45
45
|
## Installation :package:
|
46
46
|
|
@@ -57,13 +57,13 @@ pip install job-shop-lib
|
|
57
57
|
See [this](https://colab.research.google.com/drive/1XV_Rvq1F2ns6DFG8uNj66q_rcowwTZ4H?usp=sharing) Google Colab notebook for a quick start guide!
|
58
58
|
|
59
59
|
|
60
|
-
Version 1.0.0 is currently in
|
60
|
+
Version 1.0.0 is currently in alpha stage and can be installed with:
|
61
61
|
|
62
62
|
```bash
|
63
|
-
pip install job-shop-lib==1.0.
|
63
|
+
pip install job-shop-lib==1.0.0a5
|
64
64
|
```
|
65
65
|
|
66
|
-
Although this version is not stable and may contain breaking changes in subsequent releases, it is recommended to install it to access the new reinforcement learning environments and
|
66
|
+
Although this version is not stable and may contain breaking changes in subsequent releases, it is recommended to install it to access the new reinforcement learning environments and familiarize yourself with new changes (see the [latest pull requests](https://github.com/Pabloo22/job_shop_lib/pulls?q=is%3Apr+is%3Aclosed)). There is a [documentation page](https://job-shop-lib.readthedocs.io/en/latest/) for versions 1.0.0a3 and onward.
|
67
67
|
|
68
68
|
<!-- end installation -->
|
69
69
|
|
@@ -71,25 +71,25 @@ Although this version is not stable and may contain breaking changes in subseque
|
|
71
71
|
|
72
72
|
## Key Features :star:
|
73
73
|
|
74
|
-
- **Data Structures**: Easily create, manage, and manipulate job shop instances and solutions with user-friendly data structures. See [Getting Started](docs/source/
|
74
|
+
- **Data Structures**: Easily create, manage, and manipulate job shop instances and solutions with user-friendly data structures. See [Getting Started](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/00-Getting-Started.ipynb) and [How Solutions are Represented](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/01-How-Solutions-are-Represented.ipynb).
|
75
75
|
|
76
|
-
- **Benchmark Instances**: Load well-known benchmark instances directly from the library without manual downloading. See [Load Benchmark Instances](docs/source/examples/05-Load-Benchmark-Instances.ipynb).
|
76
|
+
- **Benchmark Instances**: Load well-known benchmark instances directly from the library without manual downloading. See [Load Benchmark Instances](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/05-Load-Benchmark-Instances.ipynb).
|
77
77
|
|
78
78
|
- **Random Instance Generation**: Create random instances with customizable sizes and properties or augment existing ones. See [`generation`](job_shop_lib/generation) package.
|
79
79
|
|
80
80
|
- **Multiple Solvers**:
|
81
|
-
- **Constraint Programming Solver**: OR-Tools' CP-SAT solver. See [Solving the Problem](docs/source/
|
81
|
+
- **Constraint Programming Solver**: OR-Tools' CP-SAT solver. See [Solving the Problem](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/02-Solving-the-Problem.ipynb).
|
82
82
|
|
83
|
-
- **Dispatching Rule Solvers**: Use any of the available dispatching rules or create custom ones. See [Dispatching Rules](docs/source/examples/03-Dispatching-Rules.ipynb).
|
83
|
+
- **Dispatching Rule Solvers**: Use any of the available dispatching rules or create custom ones. See [Dispatching Rules](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/03-Dispatching-Rules.ipynb).
|
84
84
|
|
85
|
-
- **Gantt Charts**: Visualize final schedules and how are they created iteratively by dispatching rule solvers or sequences of scheduling decisions with GIFs or videos. See [Save Gif](docs/source/examples/06-Save-Gif.ipynb).
|
85
|
+
- **Gantt Charts**: Visualize final schedules and how are they created iteratively by dispatching rule solvers or sequences of scheduling decisions with GIFs or videos. See [Save Gif](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/06-Save-Gif.ipynb).
|
86
86
|
|
87
87
|
- **Graph Representations**:
|
88
|
-
- **Disjunctive Graphs**: Represent and visualize instances as disjunctive graphs. See [Disjunctive Graph](docs/source/examples/04-Disjunctive-Graph.ipynb).
|
89
|
-
- **Agent-Task Graphs**: Encode instances as agent-task graphs (introduced in [ScheduleNet paper](https://arxiv.org/abs/2106.03051)). See [Agent-Task Graph](docs/source/examples/07-Agent-Task-Graph.ipynb).
|
88
|
+
- **Disjunctive Graphs**: Represent and visualize instances as disjunctive graphs. See [Disjunctive Graph](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/04-Disjunctive-Graph.ipynb).
|
89
|
+
- **Agent-Task Graphs**: Encode instances as agent-task graphs (introduced in [ScheduleNet paper](https://arxiv.org/abs/2106.03051)). See [Agent-Task Graph](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/07-Agent-Task-Graph.ipynb).
|
90
90
|
- Build your own custom graphs with the `JobShopGraph` class.
|
91
91
|
|
92
|
-
- **Gymnasium Environments**: Two environments for solving the problem with Graph Neural Networks (GNNs) or any other method, and Reinforcement Learning (RL). See [SingleJobShopGraphEnv](docs/source/examples/09-SingleJobShopGraphEnv.ipynb) and [MultiJobShopGraphEnv](examples/10-MultiJobShopGraphEnv.ipynb).
|
92
|
+
- **Gymnasium Environments**: Two environments for solving the problem with Graph Neural Networks (GNNs) or any other method, and Reinforcement Learning (RL). See [SingleJobShopGraphEnv](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/09-SingleJobShopGraphEnv.ipynb) and [MultiJobShopGraphEnv](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/10-MultiJobShopGraphEnv.ipynb).
|
93
93
|
|
94
94
|
<!-- end key features -->
|
95
95
|
|
@@ -16,7 +16,7 @@ JobShopLib is a Python package for creating, solving, and visualizing Job Shop S
|
|
16
16
|
|
17
17
|
It follows a modular design, allowing users to easily extend the library with new solvers, dispatching rules, visualization functions, etc.
|
18
18
|
|
19
|
-
See the [documentation](https://job-shop-lib.readthedocs.io/en/latest/) for more details about the latest version
|
19
|
+
See the [documentation](https://job-shop-lib.readthedocs.io/en/latest/) for more details about the latest version.
|
20
20
|
|
21
21
|
## Installation :package:
|
22
22
|
|
@@ -33,13 +33,13 @@ pip install job-shop-lib
|
|
33
33
|
See [this](https://colab.research.google.com/drive/1XV_Rvq1F2ns6DFG8uNj66q_rcowwTZ4H?usp=sharing) Google Colab notebook for a quick start guide!
|
34
34
|
|
35
35
|
|
36
|
-
Version 1.0.0 is currently in
|
36
|
+
Version 1.0.0 is currently in alpha stage and can be installed with:
|
37
37
|
|
38
38
|
```bash
|
39
|
-
pip install job-shop-lib==1.0.
|
39
|
+
pip install job-shop-lib==1.0.0a5
|
40
40
|
```
|
41
41
|
|
42
|
-
Although this version is not stable and may contain breaking changes in subsequent releases, it is recommended to install it to access the new reinforcement learning environments and
|
42
|
+
Although this version is not stable and may contain breaking changes in subsequent releases, it is recommended to install it to access the new reinforcement learning environments and familiarize yourself with new changes (see the [latest pull requests](https://github.com/Pabloo22/job_shop_lib/pulls?q=is%3Apr+is%3Aclosed)). There is a [documentation page](https://job-shop-lib.readthedocs.io/en/latest/) for versions 1.0.0a3 and onward.
|
43
43
|
|
44
44
|
<!-- end installation -->
|
45
45
|
|
@@ -47,25 +47,25 @@ Although this version is not stable and may contain breaking changes in subseque
|
|
47
47
|
|
48
48
|
## Key Features :star:
|
49
49
|
|
50
|
-
- **Data Structures**: Easily create, manage, and manipulate job shop instances and solutions with user-friendly data structures. See [Getting Started](docs/source/
|
50
|
+
- **Data Structures**: Easily create, manage, and manipulate job shop instances and solutions with user-friendly data structures. See [Getting Started](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/00-Getting-Started.ipynb) and [How Solutions are Represented](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/01-How-Solutions-are-Represented.ipynb).
|
51
51
|
|
52
|
-
- **Benchmark Instances**: Load well-known benchmark instances directly from the library without manual downloading. See [Load Benchmark Instances](docs/source/examples/05-Load-Benchmark-Instances.ipynb).
|
52
|
+
- **Benchmark Instances**: Load well-known benchmark instances directly from the library without manual downloading. See [Load Benchmark Instances](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/05-Load-Benchmark-Instances.ipynb).
|
53
53
|
|
54
54
|
- **Random Instance Generation**: Create random instances with customizable sizes and properties or augment existing ones. See [`generation`](job_shop_lib/generation) package.
|
55
55
|
|
56
56
|
- **Multiple Solvers**:
|
57
|
-
- **Constraint Programming Solver**: OR-Tools' CP-SAT solver. See [Solving the Problem](docs/source/
|
57
|
+
- **Constraint Programming Solver**: OR-Tools' CP-SAT solver. See [Solving the Problem](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/tutorial/02-Solving-the-Problem.ipynb).
|
58
58
|
|
59
|
-
- **Dispatching Rule Solvers**: Use any of the available dispatching rules or create custom ones. See [Dispatching Rules](docs/source/examples/03-Dispatching-Rules.ipynb).
|
59
|
+
- **Dispatching Rule Solvers**: Use any of the available dispatching rules or create custom ones. See [Dispatching Rules](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/03-Dispatching-Rules.ipynb).
|
60
60
|
|
61
|
-
- **Gantt Charts**: Visualize final schedules and how are they created iteratively by dispatching rule solvers or sequences of scheduling decisions with GIFs or videos. See [Save Gif](docs/source/examples/06-Save-Gif.ipynb).
|
61
|
+
- **Gantt Charts**: Visualize final schedules and how are they created iteratively by dispatching rule solvers or sequences of scheduling decisions with GIFs or videos. See [Save Gif](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/06-Save-Gif.ipynb).
|
62
62
|
|
63
63
|
- **Graph Representations**:
|
64
|
-
- **Disjunctive Graphs**: Represent and visualize instances as disjunctive graphs. See [Disjunctive Graph](docs/source/examples/04-Disjunctive-Graph.ipynb).
|
65
|
-
- **Agent-Task Graphs**: Encode instances as agent-task graphs (introduced in [ScheduleNet paper](https://arxiv.org/abs/2106.03051)). See [Agent-Task Graph](docs/source/examples/07-Agent-Task-Graph.ipynb).
|
64
|
+
- **Disjunctive Graphs**: Represent and visualize instances as disjunctive graphs. See [Disjunctive Graph](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/04-Disjunctive-Graph.ipynb).
|
65
|
+
- **Agent-Task Graphs**: Encode instances as agent-task graphs (introduced in [ScheduleNet paper](https://arxiv.org/abs/2106.03051)). See [Agent-Task Graph](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/07-Agent-Task-Graph.ipynb).
|
66
66
|
- Build your own custom graphs with the `JobShopGraph` class.
|
67
67
|
|
68
|
-
- **Gymnasium Environments**: Two environments for solving the problem with Graph Neural Networks (GNNs) or any other method, and Reinforcement Learning (RL). See [SingleJobShopGraphEnv](docs/source/examples/09-SingleJobShopGraphEnv.ipynb) and [MultiJobShopGraphEnv](examples/10-MultiJobShopGraphEnv.ipynb).
|
68
|
+
- **Gymnasium Environments**: Two environments for solving the problem with Graph Neural Networks (GNNs) or any other method, and Reinforcement Learning (RL). See [SingleJobShopGraphEnv](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/09-SingleJobShopGraphEnv.ipynb) and [MultiJobShopGraphEnv](https://github.com/Pabloo22/job_shop_lib/blob/main/docs/source/examples/10-MultiJobShopGraphEnv.ipynb).
|
69
69
|
|
70
70
|
<!-- end key features -->
|
71
71
|
|
@@ -19,6 +19,8 @@ from job_shop_lib._schedule import Schedule
|
|
19
19
|
from job_shop_lib._base_solver import BaseSolver, Solver
|
20
20
|
|
21
21
|
|
22
|
+
__version__ = "1.0.0-a.5"
|
23
|
+
|
22
24
|
__all__ = [
|
23
25
|
"Operation",
|
24
26
|
"JobShopInstance",
|
@@ -26,4 +28,5 @@ __all__ = [
|
|
26
28
|
"Schedule",
|
27
29
|
"Solver",
|
28
30
|
"BaseSolver",
|
31
|
+
"__version__",
|
29
32
|
]
|
@@ -15,16 +15,47 @@ from job_shop_lib import Operation
|
|
15
15
|
class JobShopInstance:
|
16
16
|
"""Data structure to store a Job Shop Scheduling Problem instance.
|
17
17
|
|
18
|
-
Additional attributes such as
|
19
|
-
from the instance and are cached for performance if they
|
20
|
-
computations.
|
18
|
+
Additional attributes such as ``num_machines`` or ``durations_matrix`` can
|
19
|
+
be computed from the instance and are cached for performance if they
|
20
|
+
require expensive computations.
|
21
|
+
|
22
|
+
Methods:
|
23
|
+
|
24
|
+
.. autosummary::
|
25
|
+
:nosignatures:
|
26
|
+
|
27
|
+
from_taillard_file
|
28
|
+
to_dict
|
29
|
+
from_matrices
|
30
|
+
set_operation_attributes
|
31
|
+
|
32
|
+
Properties:
|
33
|
+
|
34
|
+
.. autosummary::
|
35
|
+
:nosignatures:
|
36
|
+
|
37
|
+
num_jobs
|
38
|
+
num_machines
|
39
|
+
num_operations
|
40
|
+
is_flexible
|
41
|
+
durations_matrix
|
42
|
+
machines_matrix
|
43
|
+
durations_matrix_array
|
44
|
+
machines_matrix_array
|
45
|
+
operations_by_machine
|
46
|
+
max_duration
|
47
|
+
max_duration_per_job
|
48
|
+
max_duration_per_machine
|
49
|
+
job_durations
|
50
|
+
machine_loads
|
51
|
+
total_duration
|
21
52
|
|
22
53
|
Attributes:
|
23
54
|
jobs (list[list[Operation]]):
|
24
55
|
A list of lists of operations. Each list of operations represents
|
25
56
|
a job, and the operations are ordered by their position in the job.
|
26
|
-
The
|
27
|
-
the operations are set when the instance is created.
|
57
|
+
The ``job_id``, ``position_in_job``, and ``operation_id``
|
58
|
+
attributes of the operations are set when the instance is created.
|
28
59
|
name (str):
|
29
60
|
A string with the name of the instance.
|
30
61
|
metadata (dict[str, Any]):
|
@@ -34,11 +65,16 @@ class JobShopInstance:
|
|
34
65
|
jobs:
|
35
66
|
A list of lists of operations. Each list of operations
|
36
67
|
represents a job, and the operations are ordered by their
|
37
|
-
position in the job. The
|
38
|
-
|
68
|
+
position in the job. The ``job_id``, ``position_in_job``, and
|
69
|
+
``operation_id`` attributes of the operations are set when the
|
39
70
|
instance is created.
|
40
71
|
name:
|
41
72
|
A string with the name of the instance.
|
73
|
+
set_operation_attributes:
|
74
|
+
If True, the ``job_id``, ``position_in_job``, and ``operation_id``
|
75
|
+
attributes of the operations are set when the instance is created.
|
76
|
+
See :meth:`set_operation_attributes` for more information. Defaults
|
77
|
+
to True.
|
42
78
|
**metadata:
|
43
79
|
Additional information about the instance.
|
44
80
|
"""
|
@@ -47,15 +83,37 @@ class JobShopInstance:
|
|
47
83
|
self,
|
48
84
|
jobs: list[list[Operation]],
|
49
85
|
name: str = "JobShopInstance",
|
86
|
+
set_operation_attributes: bool = True,
|
50
87
|
**metadata: Any,
|
51
88
|
):
|
52
89
|
self.jobs: list[list[Operation]] = jobs
|
53
|
-
|
90
|
+
if set_operation_attributes:
|
91
|
+
self.set_operation_attributes()
|
54
92
|
self.name: str = name
|
55
93
|
self.metadata: dict[str, Any] = metadata
|
56
94
|
|
57
95
|
def set_operation_attributes(self):
|
58
|
-
"""Sets the job_id and
|
96
|
+
"""Sets the ``job_id``, ``position_in_job``, and ``operation_id``
|
97
|
+
attributes for each operation in the instance.
|
98
|
+
|
99
|
+
The ``job_id`` attribute is set to the id of the job to which the
|
100
|
+
operation belongs.
|
101
|
+
|
102
|
+
The ``position_in_job`` attribute is set to the
|
103
|
+
position of the operation in the job (starts from 0).
|
104
|
+
|
105
|
+
The ``operation_id`` attribute is set to a unique identifier for the
|
106
|
+
operation (starting from 0).
|
107
|
+
|
108
|
+
The formula to compute the ``operation_id`` in a job shop instance with
|
109
|
+
a fixed number of operations per job is:
|
110
|
+
|
111
|
+
.. code-block:: python
|
112
|
+
|
113
|
+
operation_id = job_id * num_operations_per_job + position_in_job
|
114
|
+
|
115
|
+
"""
|
116
|
+
|
59
117
|
operation_id = 0
|
60
118
|
for job_id, job in enumerate(self.jobs):
|
61
119
|
for position, operation in enumerate(job):
|
@@ -90,8 +148,8 @@ class JobShopInstance:
|
|
90
148
|
Additional information about the instance.
|
91
149
|
|
92
150
|
Returns:
|
93
|
-
A JobShopInstance object with the operations read from the
|
94
|
-
and the name and metadata provided.
|
151
|
+
A :class:`JobShopInstance` object with the operations read from the
|
152
|
+
file, and the name and metadata provided.
|
95
153
|
"""
|
96
154
|
with open(file_path, "r", encoding=encoding) as file:
|
97
155
|
lines = file.readlines()
|
@@ -128,13 +186,17 @@ class JobShopInstance:
|
|
128
186
|
like Taillard's.
|
129
187
|
|
130
188
|
Returns:
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
189
|
+
dict[str, Any]: The returned dictionary has the following
|
190
|
+
structure:
|
191
|
+
|
192
|
+
.. code-block:: python
|
193
|
+
|
194
|
+
{
|
195
|
+
"name": self.name,
|
196
|
+
"duration_matrix": self.durations_matrix,
|
197
|
+
"machines_matrix": self.machines_matrix,
|
198
|
+
"metadata": self.metadata,
|
199
|
+
}
|
138
200
|
"""
|
139
201
|
return {
|
140
202
|
"name": self.name,
|
@@ -151,7 +213,8 @@ class JobShopInstance:
|
|
151
213
|
name: str = "JobShopInstance",
|
152
214
|
metadata: dict[str, Any] | None = None,
|
153
215
|
) -> JobShopInstance:
|
154
|
-
"""Creates a JobShopInstance from duration and machines
|
216
|
+
"""Creates a :class:`JobShopInstance` from duration and machines
|
217
|
+
matrices.
|
155
218
|
|
156
219
|
Args:
|
157
220
|
duration_matrix:
|
@@ -168,7 +231,7 @@ class JobShopInstance:
|
|
168
231
|
A dictionary with additional information about the instance.
|
169
232
|
|
170
233
|
Returns:
|
171
|
-
A JobShopInstance object.
|
234
|
+
A :class:`JobShopInstance` object.
|
172
235
|
"""
|
173
236
|
jobs: list[list[Operation]] = [[] for _ in range(len(duration_matrix))]
|
174
237
|
|
@@ -220,7 +283,7 @@ class JobShopInstance:
|
|
220
283
|
|
221
284
|
@functools.cached_property
|
222
285
|
def is_flexible(self) -> bool:
|
223
|
-
"""Returns True if any operation has more than one machine."""
|
286
|
+
"""Returns ``True`` if any operation has more than one machine."""
|
224
287
|
return any(
|
225
288
|
any(len(operation.machines) > 1 for operation in job)
|
226
289
|
for job in self.jobs
|
@@ -230,12 +293,14 @@ class JobShopInstance:
|
|
230
293
|
def durations_matrix(self) -> list[list[int]]:
|
231
294
|
"""Returns the duration matrix of the instance.
|
232
295
|
|
233
|
-
The duration of the operation with
|
234
|
-
is stored in the i-th position of the j-th list of the returned
|
296
|
+
The duration of the operation with ``job_id`` i and ``position_in_job``
|
297
|
+
j is stored in the i-th position of the j-th list of the returned
|
298
|
+
matrix:
|
299
|
+
|
300
|
+
.. code-block:: python
|
301
|
+
|
302
|
+
duration = instance.durations_matrix[i][j]
|
235
303
|
|
236
|
-
```python
|
237
|
-
duration = instance.durations_matrix[i][j]
|
238
|
-
```
|
239
304
|
"""
|
240
305
|
return [[operation.duration for operation in job] for job in self.jobs]
|
241
306
|
|
@@ -252,9 +317,9 @@ class JobShopInstance:
|
|
252
317
|
To access the machines of the operation with position i in the job
|
253
318
|
with id j, the following code must be used:
|
254
319
|
|
255
|
-
|
256
|
-
|
257
|
-
|
320
|
+
.. code-block:: python
|
321
|
+
|
322
|
+
machines = instance.machines_matrix[j][i]
|
258
323
|
|
259
324
|
"""
|
260
325
|
if self.is_flexible:
|
@@ -269,8 +334,9 @@ class JobShopInstance:
|
|
269
334
|
def durations_matrix_array(self) -> NDArray[np.float32]:
|
270
335
|
"""Returns the duration matrix of the instance as a numpy array.
|
271
336
|
|
272
|
-
The returned array has shape (num_jobs
|
273
|
-
|
337
|
+
The returned array has shape (``num_jobs``,
|
338
|
+
``max_num_operations_per_job``).
|
339
|
+
Non-existing operations are filled with ``np.nan``.
|
274
340
|
|
275
341
|
Example:
|
276
342
|
>>> jobs = [[Operation(0, 2), Operation(1, 3)], [Operation(0, 4)]]
|
@@ -286,9 +352,9 @@ class JobShopInstance:
|
|
286
352
|
def machines_matrix_array(self) -> NDArray[np.float32]:
|
287
353
|
"""Returns the machines matrix of the instance as a numpy array.
|
288
354
|
|
289
|
-
The returned array has shape (num_jobs
|
290
|
-
max_num_machines_per_operation).
|
291
|
-
np.nan
|
355
|
+
The returned array has shape (``num_jobs``,
|
356
|
+
``max_num_operations_per_job``, ``max_num_machines_per_operation``).
|
357
|
+
Non-existing machines are filled with ``np.nan``.
|
292
358
|
|
293
359
|
Example:
|
294
360
|
>>> jobs = [
|
@@ -411,7 +477,7 @@ class JobShopInstance:
|
|
411
477
|
def _fill_matrix_with_nans_2d(
|
412
478
|
matrix: list[list[int]],
|
413
479
|
) -> NDArray[np.float32]:
|
414
|
-
"""Fills a matrix with np.nan values.
|
480
|
+
"""Fills a matrix with ``np.nan`` values.
|
415
481
|
|
416
482
|
Args:
|
417
483
|
matrix:
|
@@ -419,7 +485,7 @@ class JobShopInstance:
|
|
419
485
|
|
420
486
|
Returns:
|
421
487
|
A numpy array with the same shape as the input matrix, filled with
|
422
|
-
np.nan values.
|
488
|
+
``np.nan`` values.
|
423
489
|
"""
|
424
490
|
max_length = max(len(row) for row in matrix)
|
425
491
|
squared_matrix = np.full(
|
@@ -433,7 +499,7 @@ class JobShopInstance:
|
|
433
499
|
def _fill_matrix_with_nans_3d(
|
434
500
|
matrix: list[list[list[int]]],
|
435
501
|
) -> NDArray[np.float32]:
|
436
|
-
"""Fills a 3D matrix with np.nan values.
|
502
|
+
"""Fills a 3D matrix with ``np.nan`` values.
|
437
503
|
|
438
504
|
Args:
|
439
505
|
matrix:
|
@@ -441,7 +507,7 @@ class JobShopInstance:
|
|
441
507
|
|
442
508
|
Returns:
|
443
509
|
A numpy array with the same shape as the input matrix, filled with
|
444
|
-
np.nan values.
|
510
|
+
``np.nan`` values.
|
445
511
|
"""
|
446
512
|
max_length = max(len(row) for row in matrix)
|
447
513
|
max_inner_length = len(matrix[0][0])
|
@@ -42,11 +42,20 @@ class Operation:
|
|
42
42
|
"The time it takes to perform the operation. Often referred"
|
43
43
|
" to as the processing time."
|
44
44
|
),
|
45
|
-
"job_id":
|
46
|
-
|
45
|
+
"job_id": (
|
46
|
+
"The id of the job the operation belongs to. Defaults to -1. "
|
47
|
+
"It is usually set by the :class:`JobShopInstance` class after "
|
48
|
+
"initialization."
|
49
|
+
),
|
50
|
+
"position_in_job": (
|
51
|
+
"The index of the operation in the job. Defaults to -1. "
|
52
|
+
"It is usually set by the :class:`JobShopInstance` class after "
|
53
|
+
"initialization."
|
54
|
+
),
|
47
55
|
"operation_id": (
|
48
56
|
"The id of the operation. This is unique within a "
|
49
|
-
":class:`JobShopInstance`."
|
57
|
+
":class:`JobShopInstance`. Defaults to -1. It is usually set by "
|
58
|
+
"the :class:`JobShopInstance` class after initialization."
|
50
59
|
),
|
51
60
|
}
|
52
61
|
|
@@ -25,6 +25,16 @@ class Schedule:
|
|
25
25
|
is_complete
|
26
26
|
add
|
27
27
|
reset
|
28
|
+
|
29
|
+
Args:
|
30
|
+
instance:
|
31
|
+
The :class:`JobShopInstance` object that the schedule is for.
|
32
|
+
schedule:
|
33
|
+
A list of lists of :class:`ScheduledOperation` objects. Each
|
34
|
+
list represents the order of operations on a machine. If
|
35
|
+
not provided, the schedule is initialized as an empty schedule.
|
36
|
+
**metadata:
|
37
|
+
Additional information about the schedule.
|
28
38
|
"""
|
29
39
|
|
30
40
|
__slots__ = {
|
@@ -48,18 +58,6 @@ class Schedule:
|
|
48
58
|
schedule: list[list[ScheduledOperation]] | None = None,
|
49
59
|
**metadata: Any,
|
50
60
|
):
|
51
|
-
"""Initializes the object with the given instance and schedule.
|
52
|
-
|
53
|
-
Args:
|
54
|
-
instance:
|
55
|
-
The :class:`JobShopInstance` object that the schedule is for.
|
56
|
-
schedule:
|
57
|
-
A list of lists of :class:`ScheduledOperation` objects. Each
|
58
|
-
list represents the order of operations on a machine. If
|
59
|
-
not provided, the schedule is initialized as an empty schedule.
|
60
|
-
**metadata:
|
61
|
-
Additional information about the schedule.
|
62
|
-
"""
|
63
61
|
if schedule is None:
|
64
62
|
schedule = [[] for _ in range(instance.num_machines)]
|
65
63
|
|
@@ -5,7 +5,21 @@ from job_shop_lib.exceptions import ValidationError
|
|
5
5
|
|
6
6
|
|
7
7
|
class ScheduledOperation:
|
8
|
-
"""Data structure to store a scheduled operation.
|
8
|
+
"""Data structure to store a scheduled operation.
|
9
|
+
|
10
|
+
Args:
|
11
|
+
operation:
|
12
|
+
The :class:`Operation` object that is scheduled.
|
13
|
+
start_time:
|
14
|
+
The time at which the operation is scheduled to start.
|
15
|
+
machine_id:
|
16
|
+
The id of the machine on which the operation is scheduled.
|
17
|
+
|
18
|
+
Raises:
|
19
|
+
ValidationError:
|
20
|
+
If the given machine_id is not in the list of valid machines
|
21
|
+
for the operation.
|
22
|
+
"""
|
9
23
|
|
10
24
|
__slots__ = {
|
11
25
|
"operation": "The :class:`Operation` object that is scheduled.",
|
@@ -16,21 +30,6 @@ class ScheduledOperation:
|
|
16
30
|
}
|
17
31
|
|
18
32
|
def __init__(self, operation: Operation, start_time: int, machine_id: int):
|
19
|
-
"""Initializes a new instance of the :class:`ScheduledOperation` class.
|
20
|
-
|
21
|
-
Args:
|
22
|
-
operation:
|
23
|
-
The :class:`Operation` object that is scheduled.
|
24
|
-
start_time:
|
25
|
-
The time at which the operation is scheduled to start.
|
26
|
-
machine_id:
|
27
|
-
The id of the machine on which the operation is scheduled.
|
28
|
-
|
29
|
-
Raises:
|
30
|
-
ValidationError:
|
31
|
-
If the given machine_id is not in the list of valid machines
|
32
|
-
for the operation.
|
33
|
-
"""
|
34
33
|
self.operation: Operation = operation
|
35
34
|
self.start_time: int = start_time
|
36
35
|
self._machine_id = machine_id
|
{job_shop_lib-1.0.0a3 → job_shop_lib-1.0.0a5}/job_shop_lib/constraint_programming/_ortools_solver.py
RENAMED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
+
from typing import Any
|
5
6
|
import time
|
6
7
|
|
7
8
|
from ortools.sat.python import cp_model
|
@@ -151,7 +152,7 @@ class ORToolsSolver(BaseSolver):
|
|
151
152
|
self._set_objective(instance)
|
152
153
|
|
153
154
|
def _create_schedule(
|
154
|
-
self, instance: JobShopInstance, metadata: dict[str,
|
155
|
+
self, instance: JobShopInstance, metadata: dict[str, Any]
|
155
156
|
) -> Schedule:
|
156
157
|
"""Creates a Schedule object from the solution."""
|
157
158
|
operations_start: dict[Operation, int] = {
|