pykp 0.0.22__tar.gz

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.
pykp-0.0.22/PKG-INFO ADDED
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.1
2
+ Name: pykp
3
+ Version: 0.0.22
4
+ Summary: Tooling for sampling and solving instances of the 0-1 Knapsack Problem
5
+ Home-page: https://github.com/HRSAndrabi/pykp
6
+ Author: Hassan Andrabi
7
+ Author-email: hrs.andrabi@gmail.com
8
+ License: MIT
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.12
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: anytree>=2.12.1
15
+ Requires-Dist: pandas>=2.2.3
16
+ Requires-Dist: matplotlib==3.9.2
17
+ Requires-Dist: numpy==2.1.3
18
+ Provides-Extra: dev
19
+ Requires-Dist: pytest>=7.0; extra == "dev"
20
+ Requires-Dist: twine>=4.0.2; extra == "dev"
21
+
22
+ # PyKP: A Python Package for Knapsack Problem Solving
23
+
24
+ PyKP is a free and open-source library for sampling and solving instances of the knapsack problem. It provides tools to define knapsack instances, solve them efficiently, and analyse computational complexity metrics. You can also use `pykp` to sample knapsack problem instances based on specified distributions.
25
+
26
+ ## Features
27
+
28
+ - Define knapsack problem instances with custom items, weights, and values.
29
+ - Solve knapsack instances using branch-and-bound and other methods.
30
+ - Compute optimal and feasible solutions for different knapsack configurations.
31
+ - Analyse computational complexity metrics.
32
+ - Generate synthetic knapsack instances with custom weight, density, and solution value ranges.
33
+
34
+ ## Installation
35
+
36
+ PyKP support Python version 3.12 and higher. To install PyKP, run
37
+
38
+ ```
39
+ pip install pykp
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ ### Defining and Solving a Knapsack Problem
45
+
46
+ To start, define a knapsack problem with a set of items and solve it using the Knapsack class.
47
+
48
+ ```python
49
+ import numpy as np
50
+ from pykp import Knapsack
51
+ from pykp import Item
52
+
53
+ # Define items for the knapsack
54
+ items = np.array([
55
+ Item(value=10, weight=5),
56
+ Item(value=15, weight=10),
57
+ Item(value=7, weight=3)
58
+ ])
59
+
60
+ # Initialise a Knapsack instance
61
+ capacity = 15
62
+ knapsack = Knapsack(items=items, capacity=capacity)
63
+ knapsack.solve()
64
+
65
+ # Display the optimal solution
66
+ print("Optimal Solution Value:", knapsack.optimal_nodes[0].value)
67
+ ```
68
+
69
+ ### Generating Knapsack Instances with Sampler
70
+
71
+ The `Sampler` class allows you to generate knapsack instances based on specific ranges for item densities (value/weight ratio) and optimal solution values.
72
+
73
+ ```python
74
+ from pykp import Sampler
75
+
76
+ # Initialise a Sampler instance with desired ranges
77
+ sampler = Sampler(
78
+ num_items=5,
79
+ normalised_capacity=0.6,
80
+ density_range=(0.5, 1.5),
81
+ solution_value_range=(100, 200)
82
+ )
83
+
84
+ # Generate a sampled knapsack instance
85
+ sampled_knapsack = sampler.sample()
86
+ print("Sampled Knapsack Capacity:", sampled_knapsack.capacity)
87
+ ```
88
+
89
+ ### Analysing Knapsack Solutions
90
+
91
+ The package provides methods to analyse the optimal solutions and other feasible arrangements.
92
+
93
+ ```python
94
+ # Display a summary of the knapsack solutions
95
+ print(sampled_knapsack.summary())
96
+ ```
97
+
98
+ ## License
99
+
100
+ This project is licensed under the MIT License.
101
+
102
+ ## Contributing
103
+
104
+ Contributions are welcome. Please fork the repository and submit a pull request.
105
+
106
+ ## Contact
107
+
108
+ For questions or feedback, please reach out at hrs.andrabi@gmail.com.
pykp-0.0.22/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # PyKP: A Python Package for Knapsack Problem Solving
2
+
3
+ PyKP is a free and open-source library for sampling and solving instances of the knapsack problem. It provides tools to define knapsack instances, solve them efficiently, and analyse computational complexity metrics. You can also use `pykp` to sample knapsack problem instances based on specified distributions.
4
+
5
+ ## Features
6
+
7
+ - Define knapsack problem instances with custom items, weights, and values.
8
+ - Solve knapsack instances using branch-and-bound and other methods.
9
+ - Compute optimal and feasible solutions for different knapsack configurations.
10
+ - Analyse computational complexity metrics.
11
+ - Generate synthetic knapsack instances with custom weight, density, and solution value ranges.
12
+
13
+ ## Installation
14
+
15
+ PyKP support Python version 3.12 and higher. To install PyKP, run
16
+
17
+ ```
18
+ pip install pykp
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ### Defining and Solving a Knapsack Problem
24
+
25
+ To start, define a knapsack problem with a set of items and solve it using the Knapsack class.
26
+
27
+ ```python
28
+ import numpy as np
29
+ from pykp import Knapsack
30
+ from pykp import Item
31
+
32
+ # Define items for the knapsack
33
+ items = np.array([
34
+ Item(value=10, weight=5),
35
+ Item(value=15, weight=10),
36
+ Item(value=7, weight=3)
37
+ ])
38
+
39
+ # Initialise a Knapsack instance
40
+ capacity = 15
41
+ knapsack = Knapsack(items=items, capacity=capacity)
42
+ knapsack.solve()
43
+
44
+ # Display the optimal solution
45
+ print("Optimal Solution Value:", knapsack.optimal_nodes[0].value)
46
+ ```
47
+
48
+ ### Generating Knapsack Instances with Sampler
49
+
50
+ The `Sampler` class allows you to generate knapsack instances based on specific ranges for item densities (value/weight ratio) and optimal solution values.
51
+
52
+ ```python
53
+ from pykp import Sampler
54
+
55
+ # Initialise a Sampler instance with desired ranges
56
+ sampler = Sampler(
57
+ num_items=5,
58
+ normalised_capacity=0.6,
59
+ density_range=(0.5, 1.5),
60
+ solution_value_range=(100, 200)
61
+ )
62
+
63
+ # Generate a sampled knapsack instance
64
+ sampled_knapsack = sampler.sample()
65
+ print("Sampled Knapsack Capacity:", sampled_knapsack.capacity)
66
+ ```
67
+
68
+ ### Analysing Knapsack Solutions
69
+
70
+ The package provides methods to analyse the optimal solutions and other feasible arrangements.
71
+
72
+ ```python
73
+ # Display a summary of the knapsack solutions
74
+ print(sampled_knapsack.summary())
75
+ ```
76
+
77
+ ## License
78
+
79
+ This project is licensed under the MIT License.
80
+
81
+ ## Contributing
82
+
83
+ Contributions are welcome. Please fork the repository and submit a pull request.
84
+
85
+ ## Contact
86
+
87
+ For questions or feedback, please reach out at hrs.andrabi@gmail.com.
@@ -0,0 +1,4 @@
1
+ from .knapsack import Knapsack
2
+ from .item import Item
3
+ from .arrangement import Arrangement
4
+ from .sampler import Sampler
@@ -0,0 +1,63 @@
1
+ import numpy as np
2
+ from .item import Item
3
+
4
+ class Arrangement():
5
+ """
6
+ Represents an arrangement of items for the knapsack problem.
7
+
8
+ Attributes:
9
+ * items (np.ndarray[Item]): An array of items for the knapsack problem.
10
+ * state (np.ndarray[int]): Binary array indicating the inclusion/exclusion of items in the arrangement.
11
+ * value (int): The total value of items in the arrangement.
12
+ * weight (int): The total weight of items in the arrangement.
13
+ """
14
+ def __init__(
15
+ self,
16
+ items: np.ndarray[Item],
17
+ state: np.ndarray[int],
18
+ ):
19
+ """Initialises an Arrangement instance.
20
+
21
+ Args:
22
+ items (np.ndarray[Item]): An array of items for the knapsack problem.
23
+ state (np.ndarray[int]): Binary array indicating the inclusion/exclusion of items in the arrangement.
24
+ capacity (int): The maximum weight capacity constraint for the arrangement.
25
+ """
26
+ if not np.all(np.isin(state, [0, 1])):
27
+ raise ValueError("Elements of `state` must be 0 or 1.")
28
+
29
+ self.items = items
30
+ self.state = state
31
+ self.value = self.__calculate_value()
32
+ self.weight = self.__calculate_weight()
33
+
34
+
35
+ def __calculate_value(self):
36
+ """
37
+ Calculates the total value of items currently in the knapsack.
38
+
39
+ Returns:
40
+ float: The total value of items in the knapsack.
41
+ """
42
+ return sum([self.items[i].value for i, inside in enumerate(self.state) if bool(inside)])
43
+
44
+
45
+ def __calculate_weight(self):
46
+ """
47
+ Calculates the total weight of items currently in the knapsack.
48
+
49
+ Returns:
50
+ float: The total weight of items in the knapsack.
51
+ """
52
+ return sum([self.items[i].weight for i, inside in enumerate(self.state) if bool(inside)])
53
+
54
+
55
+ def __str__(self):
56
+ state = int("".join(self.state.astype(int).astype(str)), 2)
57
+ return f"(v: {self.value}, w: {self.weight}, s: {state})"
58
+
59
+ def __repr__(self):
60
+ state = int("".join(self.state.astype(int).astype(str)), 2)
61
+ return f"(v: {self.value}, w: {self.weight}, s: {state})"
62
+
63
+
@@ -0,0 +1,40 @@
1
+ class Item:
2
+ """
3
+ Represents an item for the knapsack problem.
4
+
5
+ Attributes:
6
+ value (int): The value of the item.
7
+ weight (int): The weight of the item.
8
+ """
9
+ def __init__(self, value: int, weight: int):
10
+ """
11
+ Initialises an Item instance.
12
+
13
+ Args:
14
+ value (int): The value of the item.
15
+ weight (int): The weight of the item.
16
+ """
17
+ self.weight = weight
18
+ self.value = value
19
+
20
+ def update_value(self, new_value: int):
21
+ """Updates the value of the item.
22
+
23
+ Args:
24
+ new_value (int): New value of the item.
25
+ """
26
+ self.value = new_value
27
+
28
+ def update_weight(self, new_weight: int):
29
+ """Updates the weight of the item.
30
+
31
+ Args:
32
+ new_weight (int): New weight of the item.
33
+ """
34
+ self.weight = new_weight
35
+
36
+ def __str__(self):
37
+ return f"weight: {self.weight}; value: {self.value}"
38
+
39
+ def __repr__(self):
40
+ return str(self)