passagemath-polyhedra 10.6.31rc3__cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.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.

Potentially problematic release.


This version of passagemath-polyhedra might be problematic. Click here for more details.

Files changed (206) hide show
  1. passagemath_polyhedra-10.6.31rc3.dist-info/METADATA +367 -0
  2. passagemath_polyhedra-10.6.31rc3.dist-info/METADATA.bak +369 -0
  3. passagemath_polyhedra-10.6.31rc3.dist-info/RECORD +206 -0
  4. passagemath_polyhedra-10.6.31rc3.dist-info/WHEEL +6 -0
  5. passagemath_polyhedra-10.6.31rc3.dist-info/top_level.txt +2 -0
  6. passagemath_polyhedra.libs/libgmp-6e109695.so.10.5.0 +0 -0
  7. passagemath_polyhedra.libs/libgomp-e985bcbb.so.1.0.0 +0 -0
  8. sage/all__sagemath_polyhedra.py +50 -0
  9. sage/game_theory/all.py +8 -0
  10. sage/game_theory/catalog.py +6 -0
  11. sage/game_theory/catalog_normal_form_games.py +923 -0
  12. sage/game_theory/cooperative_game.py +844 -0
  13. sage/game_theory/matching_game.py +1181 -0
  14. sage/game_theory/normal_form_game.py +2697 -0
  15. sage/game_theory/parser.py +275 -0
  16. sage/geometry/all__sagemath_polyhedra.py +22 -0
  17. sage/geometry/cone.py +6940 -0
  18. sage/geometry/cone_catalog.py +847 -0
  19. sage/geometry/cone_critical_angles.py +1027 -0
  20. sage/geometry/convex_set.py +1119 -0
  21. sage/geometry/fan.py +3743 -0
  22. sage/geometry/fan_isomorphism.py +389 -0
  23. sage/geometry/fan_morphism.py +1884 -0
  24. sage/geometry/hasse_diagram.py +202 -0
  25. sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
  26. sage/geometry/hyperplane_arrangement/all.py +1 -0
  27. sage/geometry/hyperplane_arrangement/arrangement.py +3895 -0
  28. sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
  29. sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
  30. sage/geometry/hyperplane_arrangement/library.py +825 -0
  31. sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
  32. sage/geometry/hyperplane_arrangement/plot.py +520 -0
  33. sage/geometry/integral_points.py +35 -0
  34. sage/geometry/integral_points_generic_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  35. sage/geometry/integral_points_generic_dense.pyx +7 -0
  36. sage/geometry/lattice_polytope.py +5894 -0
  37. sage/geometry/linear_expression.py +773 -0
  38. sage/geometry/newton_polygon.py +767 -0
  39. sage/geometry/point_collection.cpython-314-x86_64-linux-gnu.so +0 -0
  40. sage/geometry/point_collection.pyx +1008 -0
  41. sage/geometry/polyhedral_complex.py +2616 -0
  42. sage/geometry/polyhedron/all.py +8 -0
  43. sage/geometry/polyhedron/backend_cdd.py +460 -0
  44. sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
  45. sage/geometry/polyhedron/backend_field.py +347 -0
  46. sage/geometry/polyhedron/backend_normaliz.py +2503 -0
  47. sage/geometry/polyhedron/backend_number_field.py +168 -0
  48. sage/geometry/polyhedron/backend_polymake.py +765 -0
  49. sage/geometry/polyhedron/backend_ppl.py +582 -0
  50. sage/geometry/polyhedron/base.py +1206 -0
  51. sage/geometry/polyhedron/base0.py +1444 -0
  52. sage/geometry/polyhedron/base1.py +886 -0
  53. sage/geometry/polyhedron/base2.py +812 -0
  54. sage/geometry/polyhedron/base3.py +1845 -0
  55. sage/geometry/polyhedron/base4.py +1262 -0
  56. sage/geometry/polyhedron/base5.py +2700 -0
  57. sage/geometry/polyhedron/base6.py +1741 -0
  58. sage/geometry/polyhedron/base7.py +997 -0
  59. sage/geometry/polyhedron/base_QQ.py +1258 -0
  60. sage/geometry/polyhedron/base_RDF.py +98 -0
  61. sage/geometry/polyhedron/base_ZZ.py +934 -0
  62. sage/geometry/polyhedron/base_mutable.py +215 -0
  63. sage/geometry/polyhedron/base_number_field.py +122 -0
  64. sage/geometry/polyhedron/cdd_file_format.py +155 -0
  65. sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
  66. sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-x86_64-linux-gnu.so +0 -0
  67. sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
  68. sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
  69. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-x86_64-linux-gnu.so +0 -0
  70. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
  71. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
  72. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-x86_64-linux-gnu.so +0 -0
  73. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
  74. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
  75. sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
  76. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-x86_64-linux-gnu.so +0 -0
  77. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
  78. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
  79. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-x86_64-linux-gnu.so +0 -0
  80. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
  81. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
  82. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-x86_64-linux-gnu.so +0 -0
  83. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
  84. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
  85. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-x86_64-linux-gnu.so +0 -0
  86. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
  87. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
  88. sage/geometry/polyhedron/constructor.py +773 -0
  89. sage/geometry/polyhedron/double_description.py +753 -0
  90. sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
  91. sage/geometry/polyhedron/face.py +1060 -0
  92. sage/geometry/polyhedron/generating_function.py +1810 -0
  93. sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
  94. sage/geometry/polyhedron/library.py +3502 -0
  95. sage/geometry/polyhedron/misc.py +121 -0
  96. sage/geometry/polyhedron/modules/all.py +1 -0
  97. sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
  98. sage/geometry/polyhedron/palp_database.py +447 -0
  99. sage/geometry/polyhedron/parent.py +1279 -0
  100. sage/geometry/polyhedron/plot.py +1986 -0
  101. sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
  102. sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
  103. sage/geometry/polyhedron/representation.py +1723 -0
  104. sage/geometry/pseudolines.py +515 -0
  105. sage/geometry/relative_interior.py +445 -0
  106. sage/geometry/toric_plotter.py +1103 -0
  107. sage/geometry/triangulation/all.py +2 -0
  108. sage/geometry/triangulation/base.cpython-314-x86_64-linux-gnu.so +0 -0
  109. sage/geometry/triangulation/base.pyx +963 -0
  110. sage/geometry/triangulation/data.h +147 -0
  111. sage/geometry/triangulation/data.pxd +4 -0
  112. sage/geometry/triangulation/element.py +914 -0
  113. sage/geometry/triangulation/functions.h +10 -0
  114. sage/geometry/triangulation/functions.pxd +4 -0
  115. sage/geometry/triangulation/point_configuration.py +2256 -0
  116. sage/geometry/triangulation/triangulations.h +49 -0
  117. sage/geometry/triangulation/triangulations.pxd +7 -0
  118. sage/geometry/voronoi_diagram.py +319 -0
  119. sage/interfaces/all__sagemath_polyhedra.py +1 -0
  120. sage/interfaces/polymake.py +2028 -0
  121. sage/numerical/all.py +13 -0
  122. sage/numerical/all__sagemath_polyhedra.py +11 -0
  123. sage/numerical/backends/all.py +1 -0
  124. sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
  125. sage/numerical/backends/cvxopt_backend.cpython-314-x86_64-linux-gnu.so +0 -0
  126. sage/numerical/backends/cvxopt_backend.pyx +1006 -0
  127. sage/numerical/backends/cvxopt_backend_test.py +19 -0
  128. sage/numerical/backends/cvxopt_sdp_backend.cpython-314-x86_64-linux-gnu.so +0 -0
  129. sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
  130. sage/numerical/backends/cvxpy_backend.cpython-314-x86_64-linux-gnu.so +0 -0
  131. sage/numerical/backends/cvxpy_backend.pxd +41 -0
  132. sage/numerical/backends/cvxpy_backend.pyx +934 -0
  133. sage/numerical/backends/cvxpy_backend_test.py +13 -0
  134. sage/numerical/backends/generic_backend_test.py +24 -0
  135. sage/numerical/backends/interactivelp_backend.cpython-314-x86_64-linux-gnu.so +0 -0
  136. sage/numerical/backends/interactivelp_backend.pxd +36 -0
  137. sage/numerical/backends/interactivelp_backend.pyx +1231 -0
  138. sage/numerical/backends/interactivelp_backend_test.py +12 -0
  139. sage/numerical/backends/logging_backend.py +391 -0
  140. sage/numerical/backends/matrix_sdp_backend.cpython-314-x86_64-linux-gnu.so +0 -0
  141. sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
  142. sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
  143. sage/numerical/backends/ppl_backend.cpython-314-x86_64-linux-gnu.so +0 -0
  144. sage/numerical/backends/ppl_backend.pyx +1126 -0
  145. sage/numerical/backends/ppl_backend_test.py +13 -0
  146. sage/numerical/backends/scip_backend.cpython-314-x86_64-linux-gnu.so +0 -0
  147. sage/numerical/backends/scip_backend.pxd +22 -0
  148. sage/numerical/backends/scip_backend.pyx +1289 -0
  149. sage/numerical/backends/scip_backend_test.py +13 -0
  150. sage/numerical/interactive_simplex_method.py +5338 -0
  151. sage/numerical/knapsack.py +665 -0
  152. sage/numerical/linear_functions.cpython-314-x86_64-linux-gnu.so +0 -0
  153. sage/numerical/linear_functions.pxd +31 -0
  154. sage/numerical/linear_functions.pyx +1648 -0
  155. sage/numerical/linear_tensor.py +470 -0
  156. sage/numerical/linear_tensor_constraints.py +448 -0
  157. sage/numerical/linear_tensor_element.cpython-314-x86_64-linux-gnu.so +0 -0
  158. sage/numerical/linear_tensor_element.pxd +6 -0
  159. sage/numerical/linear_tensor_element.pyx +459 -0
  160. sage/numerical/mip.cpython-314-x86_64-linux-gnu.so +0 -0
  161. sage/numerical/mip.pxd +40 -0
  162. sage/numerical/mip.pyx +3667 -0
  163. sage/numerical/sdp.cpython-314-x86_64-linux-gnu.so +0 -0
  164. sage/numerical/sdp.pxd +39 -0
  165. sage/numerical/sdp.pyx +1433 -0
  166. sage/rings/all__sagemath_polyhedra.py +3 -0
  167. sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
  168. sage/rings/polynomial/omega.py +982 -0
  169. sage/schemes/all__sagemath_polyhedra.py +2 -0
  170. sage/schemes/toric/all.py +10 -0
  171. sage/schemes/toric/chow_group.py +1248 -0
  172. sage/schemes/toric/divisor.py +2082 -0
  173. sage/schemes/toric/divisor_class.cpython-314-x86_64-linux-gnu.so +0 -0
  174. sage/schemes/toric/divisor_class.pyx +322 -0
  175. sage/schemes/toric/fano_variety.py +1606 -0
  176. sage/schemes/toric/homset.py +650 -0
  177. sage/schemes/toric/ideal.py +451 -0
  178. sage/schemes/toric/library.py +1322 -0
  179. sage/schemes/toric/morphism.py +1958 -0
  180. sage/schemes/toric/points.py +1032 -0
  181. sage/schemes/toric/sheaf/all.py +1 -0
  182. sage/schemes/toric/sheaf/constructor.py +302 -0
  183. sage/schemes/toric/sheaf/klyachko.py +921 -0
  184. sage/schemes/toric/toric_subscheme.py +905 -0
  185. sage/schemes/toric/variety.py +3460 -0
  186. sage/schemes/toric/weierstrass.py +1078 -0
  187. sage/schemes/toric/weierstrass_covering.py +457 -0
  188. sage/schemes/toric/weierstrass_higher.py +288 -0
  189. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
  190. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
  191. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
  192. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
  193. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
  194. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
  195. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
  196. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
  197. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
  198. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
  199. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
  200. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
  201. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
  202. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
  203. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
  204. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
  205. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
  206. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
@@ -0,0 +1,665 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ r"""
3
+ Knapsack Problems
4
+
5
+ This module implements a number of solutions to various knapsack problems,
6
+ otherwise known as linear integer programming problems. Solutions to the
7
+ following knapsack problems are implemented:
8
+
9
+ - Solving the subset sum problem for super-increasing sequences.
10
+ - General case using Linear Programming
11
+
12
+ AUTHORS:
13
+
14
+ - Minh Van Nguyen (2009-04): initial version
15
+ - Nathann Cohen (2009-08): Linear Programming version
16
+
17
+ Definition of Knapsack problems
18
+ -------------------------------
19
+
20
+ You have already had a knapsack problem, so you should know, but in case you do
21
+ not, a knapsack problem is what happens when you have hundred of items to put
22
+ into a bag which is too small, and you want to pack the most useful of them.
23
+
24
+ When you formally write it, here is your problem:
25
+
26
+ * Your bag can contain a weight of at most `W`.
27
+ * Each item `i` has a weight `w_i`.
28
+ * Each item `i` has a usefulness `u_i`.
29
+
30
+ You then want to maximize the total usefulness of the items you will store into
31
+ your bag, while keeping sure the weight of the bag will not go over `W`.
32
+
33
+ As a linear program, this problem can be represented this way (if you define
34
+ `b_i` as the binary variable indicating whether the item `i` is to be included
35
+ in your bag):
36
+
37
+ .. MATH::
38
+
39
+ \mbox{Maximize: }\sum_i b_i u_i \\
40
+ \mbox{Such that: }
41
+ \sum_i b_i w_i \leq W \\
42
+ \forall i, b_i \mbox{ binary variable} \\
43
+
44
+ (For more information, see the :wikipedia:`Knapsack_problem`)
45
+
46
+ Examples
47
+ --------
48
+
49
+ If your knapsack problem is composed of three items (weight, value)
50
+ defined by (1,2), (1.5,1), (0.5,3), and a bag of maximum weight 2,
51
+ you can easily solve it this way::
52
+
53
+ sage: from sage.numerical.knapsack import knapsack
54
+ sage: knapsack( [(1,2), (1.5,1), (0.5,3)], max=2)
55
+ [5.0, [(1, 2), (0.500000000000000, 3)]]
56
+
57
+ Super-increasing sequences
58
+ --------------------------
59
+
60
+ We can test for whether or not a sequence is super-increasing::
61
+
62
+ sage: from sage.numerical.knapsack import Superincreasing
63
+ sage: L = [1, 2, 5, 21, 69, 189, 376, 919]
64
+ sage: seq = Superincreasing(L)
65
+ sage: seq
66
+ Super-increasing sequence of length 8
67
+ sage: seq.is_superincreasing()
68
+ True
69
+ sage: Superincreasing().is_superincreasing([1,3,5,7])
70
+ False
71
+
72
+ Solving the subset sum problem for a super-increasing sequence
73
+ and target sum::
74
+
75
+ sage: L = [1, 2, 5, 21, 69, 189, 376, 919]
76
+ sage: Superincreasing(L).subset_sum(98)
77
+ [69, 21, 5, 2, 1]
78
+ """
79
+
80
+ # ***************************************************************************
81
+ # Copyright (C) 2009 Minh Van Nguyen <nguyenminh2@gmail.com>
82
+ #
83
+ # Distributed under the terms of the GNU General Public License (GPL)
84
+ #
85
+ # https://www.gnu.org/licenses/
86
+ #
87
+ # This program is free software; you can redistribute it and/or modify
88
+ # it under the terms of the GNU General Public License as published by
89
+ # the Free Software Foundation; either version 2 of the License, or
90
+ # (at your option) any later version.
91
+ #
92
+ # This program is distributed in the hope that it will be useful,
93
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
94
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
95
+ # GNU General Public License for more details.
96
+ # ***************************************************************************
97
+
98
+ from sage.misc.latex import latex
99
+ from sage.rings.integer import Integer
100
+ from sage.structure.sage_object import SageObject
101
+
102
+
103
+ class Superincreasing(SageObject):
104
+ r"""
105
+ A class for super-increasing sequences.
106
+
107
+ Let `L = (a_1, a_2, a_3, \dots, a_n)` be a non-empty sequence of
108
+ nonnegative integers. Then `L` is said to be super-increasing if
109
+ each `a_i` is strictly greater than the sum of all previous values.
110
+ That is, for each `a_i \in L` the sequence `L` must satisfy the property
111
+
112
+ .. MATH::
113
+
114
+ a_i > \sum_{k=1}^{i-1} a_k
115
+
116
+ in order to be called a super-increasing sequence, where `|L| \geq 2`.
117
+ If `L` has only one element, it is also defined to be a
118
+ super-increasing sequence.
119
+
120
+ If ``seq`` is ``None``, then construct an empty sequence. By
121
+ definition, this empty sequence is not super-increasing.
122
+
123
+ INPUT:
124
+
125
+ - ``seq`` -- (default: ``None``) a non-empty sequence
126
+
127
+ EXAMPLES::
128
+
129
+ sage: from sage.numerical.knapsack import Superincreasing
130
+ sage: L = [1, 2, 5, 21, 69, 189, 376, 919]
131
+ sage: Superincreasing(L).is_superincreasing()
132
+ True
133
+ sage: Superincreasing().is_superincreasing([1,3,5,7])
134
+ False
135
+ sage: seq = Superincreasing(); seq
136
+ An empty sequence.
137
+ sage: seq = Superincreasing([1, 3, 6]); seq
138
+ Super-increasing sequence of length 3
139
+ sage: seq = Superincreasing([1, 2, 5, 21, 69, 189, 376, 919]); seq
140
+ Super-increasing sequence of length 8
141
+ """
142
+
143
+ def __init__(self, seq=None):
144
+ r"""
145
+ Constructing a super-increasing sequence object from ``seq``.
146
+
147
+ If ``seq`` is ``None``, then construct an empty sequence. By
148
+ definition, this empty sequence is not super-increasing.
149
+
150
+
151
+ INPUT:
152
+
153
+ - ``seq`` -- (default: ``None``) a non-empty sequence
154
+
155
+ EXAMPLES::
156
+
157
+ sage: from sage.numerical.knapsack import Superincreasing
158
+ sage: L = [1, 2, 5, 21, 69, 189, 376, 919]
159
+ sage: Superincreasing(L).is_superincreasing()
160
+ True
161
+ sage: Superincreasing().is_superincreasing([1,3,5,7])
162
+ False
163
+ """
164
+ # argument seq is None, so construct an empty sequence
165
+ if seq is None:
166
+ self._seq = None
167
+ # now seq is known to be not None, so try to construct a
168
+ # super-increasing sequence from seq
169
+ else:
170
+ if self.is_superincreasing(seq):
171
+ self._seq = seq
172
+ else:
173
+ raise ValueError("seq must be a super-increasing sequence")
174
+
175
+ def __eq__(self, other):
176
+ r"""
177
+ Comparing ``self`` to ``other``.
178
+
179
+ TESTS::
180
+
181
+ sage: from sage.numerical.knapsack import Superincreasing
182
+ sage: L = [1, 2, 5, 21, 69, 189, 376, 919]
183
+ sage: seq = Superincreasing(L)
184
+ sage: seq == loads(dumps(seq))
185
+ True
186
+ """
187
+ return self._seq == other._seq
188
+
189
+ def __ne__(self, other):
190
+ r"""
191
+ Comparing ``self`` to ``other``.
192
+
193
+ TESTS::
194
+
195
+ sage: from sage.numerical.knapsack import Superincreasing
196
+ sage: L = [1, 2, 5, 21, 69, 189, 376, 919]
197
+ sage: seq = Superincreasing(L)
198
+ sage: seq != seq
199
+ False
200
+ """
201
+ return not self.__eq__(other)
202
+
203
+ def __repr__(self):
204
+ r"""
205
+ Return a string representation of this super-increasing
206
+ sequence object.
207
+
208
+ EXAMPLES::
209
+
210
+ sage: from sage.numerical.knapsack import Superincreasing
211
+ sage: seq = Superincreasing(); seq
212
+ An empty sequence.
213
+ sage: seq = Superincreasing([1, 3, 6]); seq
214
+ Super-increasing sequence of length 3
215
+ sage: seq = Superincreasing([1, 2, 5, 21, 69, 189, 376, 919]); seq
216
+ Super-increasing sequence of length 8
217
+ """
218
+ if self._seq is None:
219
+ return "An empty sequence."
220
+ else:
221
+ return "Super-increasing sequence of length %s" % len(self._seq)
222
+
223
+ def largest_less_than(self, N):
224
+ r"""
225
+ Return the largest integer in the sequence ``self`` that is less than
226
+ or equal to ``N``.
227
+
228
+ This function narrows down the candidate solution using a binary trim,
229
+ similar to the way binary search halves the sequence at each iteration.
230
+
231
+
232
+ INPUT:
233
+
234
+ - ``N`` -- integer; the target value to search for
235
+
236
+ OUTPUT:
237
+
238
+ The largest integer in ``self`` that is less than or equal to ``N``. If
239
+ no solution exists, then return ``None``.
240
+
241
+ EXAMPLES:
242
+
243
+ When a solution is found, return it::
244
+
245
+ sage: from sage.numerical.knapsack import Superincreasing
246
+ sage: L = [2, 3, 7, 25, 67, 179, 356, 819]
247
+ sage: Superincreasing(L).largest_less_than(207)
248
+ 179
249
+ sage: L = (2, 3, 7, 25, 67, 179, 356, 819)
250
+ sage: Superincreasing(L).largest_less_than(2)
251
+ 2
252
+
253
+ But if no solution exists, return ``None``::
254
+
255
+ sage: L = [2, 3, 7, 25, 67, 179, 356, 819]
256
+ sage: Superincreasing(L).largest_less_than(-1) is None
257
+ True
258
+
259
+ TESTS:
260
+
261
+ The target ``N`` must be an integer::
262
+
263
+ sage: from sage.numerical.knapsack import Superincreasing
264
+ sage: L = [2, 3, 7, 25, 67, 179, 356, 819]
265
+ sage: Superincreasing(L).largest_less_than(2.30)
266
+ Traceback (most recent call last):
267
+ ...
268
+ TypeError: N (= 2.30000000000000) must be an integer.
269
+
270
+ The sequence that ``self`` represents must also be non-empty::
271
+
272
+ sage: Superincreasing([]).largest_less_than(2)
273
+ Traceback (most recent call last):
274
+ ...
275
+ ValueError: seq must be a super-increasing sequence
276
+ sage: Superincreasing(list()).largest_less_than(2)
277
+ Traceback (most recent call last):
278
+ ...
279
+ ValueError: seq must be a super-increasing sequence
280
+ """
281
+ from sage.functions.other import Function_floor
282
+ floor = Function_floor()
283
+ # input error handling
284
+ if len(self._seq) == 0:
285
+ raise TypeError("self must be a non-empty list of integers.")
286
+ if (not isinstance(N, Integer)) and (not isinstance(N, int)):
287
+ raise TypeError("N (= %s) must be an integer." % N)
288
+
289
+ # halving the list at each iteration, just like binary search
290
+ # TODO: some error handling to ensure that self only contains integers?
291
+ low = 0
292
+ high = len(self._seq) - 1
293
+ while low <= high:
294
+ mid = floor((low + high) / 2)
295
+ if N == self._seq[mid]:
296
+ return self._seq[mid]
297
+ if N < self._seq[mid]:
298
+ high = mid - 1
299
+ else:
300
+ low = mid + 1
301
+ if N >= self._seq[high]:
302
+ return self._seq[high]
303
+ else:
304
+ return None
305
+
306
+ def _latex_(self):
307
+ r"""
308
+ Return LaTeX representation of ``self``.
309
+
310
+ EXAMPLES::
311
+
312
+ sage: from sage.numerical.knapsack import Superincreasing
313
+ sage: latex(Superincreasing())
314
+ \left[\right]
315
+ sage: seq = Superincreasing([1, 2, 5, 21, 69, 189, 376, 919])
316
+ sage: latex(seq)
317
+ <BLANKLINE>
318
+ \left[1,
319
+ 2,
320
+ 5,
321
+ 21,
322
+ 69,
323
+ 189,
324
+ 376,
325
+ 919\right]
326
+ """
327
+ if self._seq is None:
328
+ return latex([])
329
+ else:
330
+ return latex(self._seq)
331
+
332
+ def is_superincreasing(self, seq=None):
333
+ r"""
334
+ Determine whether or not ``seq`` is super-increasing.
335
+
336
+ If ``seq=None`` then determine whether or not ``self`` is
337
+ super-increasing.
338
+
339
+ Let `L = (a_1, a_2, a_3, \dots, a_n)` be a non-empty sequence of
340
+ nonnegative integers. Then `L` is said to be super-increasing if
341
+ each `a_i` is strictly greater than the sum of all previous values.
342
+ That is, for each `a_i \in L` the sequence `L` must satisfy the
343
+ property
344
+
345
+ .. MATH::
346
+
347
+ a_i > \sum_{k=1}^{i-1} a_k
348
+
349
+ in order to be called a super-increasing sequence, where `|L| \geq 2`.
350
+ If `L` has exactly one element, then it is also defined to be a
351
+ super-increasing sequence.
352
+
353
+ INPUT:
354
+
355
+ - ``seq`` -- (default: ``None``) a sequence to test
356
+
357
+ OUTPUT:
358
+
359
+ - If ``seq`` is ``None``, then test ``self`` to determine whether or
360
+ not it is super-increasing. In that case, return ``True`` if
361
+ ``self`` is super-increasing; ``False`` otherwise.
362
+
363
+ - If ``seq`` is not ``None``, then test ``seq`` to determine whether
364
+ or not it is super-increasing. Return ``True`` if ``seq`` is
365
+ super-increasing; ``False`` otherwise.
366
+
367
+ EXAMPLES:
368
+
369
+ By definition, an empty sequence is not super-increasing::
370
+
371
+ sage: from sage.numerical.knapsack import Superincreasing
372
+ sage: Superincreasing().is_superincreasing([])
373
+ False
374
+ sage: Superincreasing().is_superincreasing()
375
+ False
376
+ sage: Superincreasing().is_superincreasing(tuple())
377
+ False
378
+ sage: Superincreasing().is_superincreasing(())
379
+ False
380
+
381
+ But here is an example of a super-increasing sequence::
382
+
383
+ sage: L = [1, 2, 5, 21, 69, 189, 376, 919]
384
+ sage: Superincreasing(L).is_superincreasing()
385
+ True
386
+ sage: L = (1, 2, 5, 21, 69, 189, 376, 919)
387
+ sage: Superincreasing(L).is_superincreasing()
388
+ True
389
+
390
+ A super-increasing sequence can have zero as one of its elements::
391
+
392
+ sage: L = [0, 1, 2, 4]
393
+ sage: Superincreasing(L).is_superincreasing()
394
+ True
395
+
396
+ A super-increasing sequence can be of length 1::
397
+
398
+ sage: Superincreasing([randint(0, 100)]).is_superincreasing()
399
+ True
400
+
401
+
402
+ TESTS:
403
+
404
+ The sequence must contain only integers::
405
+
406
+ sage: # needs sage.symbolic
407
+ sage: from sage.numerical.knapsack import Superincreasing
408
+ sage: L = [1.0, 2.1, pi, 21, 69, 189, 376, 919]
409
+ sage: Superincreasing(L).is_superincreasing()
410
+ Traceback (most recent call last):
411
+ ...
412
+ TypeError: Element e (= 1.00000000000000) of seq must be a nonnegative integer.
413
+ sage: L = [1, 2.1, pi, 21, 69, 189, 376, 919]
414
+ sage: Superincreasing(L).is_superincreasing()
415
+ Traceback (most recent call last):
416
+ ...
417
+ TypeError: Element e (= 2.10000000000000) of seq must be a nonnegative integer.
418
+ """
419
+ # argument seq is None, so test self for super-increasing
420
+ if seq is None:
421
+ # self must be a non-empty sequence
422
+ if (self._seq is None) or len(self._seq) == 0:
423
+ return False
424
+ # so now self is known to represent a non-empty sequence
425
+ if (not isinstance(self._seq[0], Integer)) and (not isinstance(self._seq[0], int)):
426
+ raise TypeError("Element e (= %s) of self must be a non-negative integer." % self._seq[0])
427
+ if self._seq[0] < 0:
428
+ raise TypeError("Element e (= %s) of self must be a non-negative integer." % self._seq[0])
429
+ cumSum = self._seq[0] # the cumulative sum of the sequence represented by self
430
+ for e in self._seq[1:]:
431
+ if (not isinstance(e, Integer)) and (not isinstance(e, int)):
432
+ raise TypeError("Element e (= %s) of self must be a non-negative integer." % e)
433
+ if e < 0:
434
+ raise TypeError("Element e (= %s) of self must be a non-negative integer." % e)
435
+ if e <= cumSum:
436
+ return False
437
+ cumSum += e
438
+ return True
439
+ # now we know that seq is not None, so test seq for super-increasing
440
+ else:
441
+ # seq must be a non-empty sequence
442
+ if len(seq) == 0:
443
+ return False
444
+ # so now seq is known to represent a non-empty sequence
445
+ if (not isinstance(seq[0], Integer)) and (not isinstance(seq[0], int)):
446
+ raise TypeError("Element e (= %s) of seq must be a nonnegative integer." % seq[0])
447
+ if seq[0] < 0:
448
+ raise TypeError("Element e (= %s) of seq must be a nonnegative integer." % seq[0])
449
+ cumSum = seq[0] # the cumulative sum of the sequence seq
450
+ for e in seq[1:]:
451
+ if (not isinstance(e, Integer)) and (not isinstance(e, int)):
452
+ raise TypeError("Element e (= %s) of seq must be a nonnegative integer." % e)
453
+ if e < 0:
454
+ raise TypeError("Element e (= %s) of seq must be a nonnegative integer." % e)
455
+ if e <= cumSum:
456
+ return False
457
+ cumSum += e
458
+ return True
459
+
460
+ def subset_sum(self, N):
461
+ r"""
462
+ Solving the subset sum problem for a super-increasing sequence.
463
+
464
+ Let `S = (s_1, s_2, s_3, \dots, s_n)` be a non-empty sequence of
465
+ nonnegative integers, and let `N \in \ZZ` be nonnegative. The
466
+ subset sum problem asks for a subset `A \subseteq S` all of whose
467
+ elements sum to `N`. This method specializes the subset sum problem
468
+ to the case of super-increasing sequences. If a solution exists, then
469
+ it is also a super-increasing sequence.
470
+
471
+ .. NOTE::
472
+
473
+ This method only solves the subset sum problem for
474
+ super-increasing sequences. In general, solving the subset sum
475
+ problem for an arbitrary sequence is known to be computationally
476
+ hard.
477
+
478
+ INPUT:
479
+
480
+ - ``N`` -- nonnegative integer
481
+
482
+ OUTPUT:
483
+
484
+ - A non-empty subset of ``self`` whose elements sum to ``N``. This
485
+ subset is also a super-increasing sequence. If no such subset
486
+ exists, then return the empty list.
487
+
488
+ ALGORITHM:
489
+
490
+ The algorithm used is adapted from page 355 of [HPS2008]_.
491
+
492
+ EXAMPLES:
493
+
494
+ Solving the subset sum problem for a super-increasing sequence
495
+ and target sum::
496
+
497
+ sage: from sage.numerical.knapsack import Superincreasing
498
+ sage: L = [1, 2, 5, 21, 69, 189, 376, 919]
499
+ sage: Superincreasing(L).subset_sum(98)
500
+ [69, 21, 5, 2, 1]
501
+
502
+
503
+ TESTS:
504
+
505
+ The target ``N`` must be a nonnegative integer::
506
+
507
+ sage: from sage.numerical.knapsack import Superincreasing
508
+ sage: L = [0, 1, 2, 4]
509
+ sage: Superincreasing(L).subset_sum(-6)
510
+ Traceback (most recent call last):
511
+ ...
512
+ TypeError: N (= -6) must be a nonnegative integer.
513
+ sage: Superincreasing(L).subset_sum(-6.2)
514
+ Traceback (most recent call last):
515
+ ...
516
+ TypeError: N (= -6.20000000000000) must be a nonnegative integer.
517
+
518
+ The sequence that ``self`` represents must only contain nonnegative
519
+ integers::
520
+
521
+ sage: L = [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1]
522
+ sage: Superincreasing(L).subset_sum(1)
523
+ Traceback (most recent call last):
524
+ ...
525
+ TypeError: Element e (= -10) of seq must be a nonnegative integer.
526
+ """
527
+ # input error handling
528
+ if not self.is_superincreasing():
529
+ raise TypeError("self is not super-increasing. Only super-increasing sequences are currently supported.")
530
+ if (not isinstance(N, Integer)) and (not isinstance(N, int)):
531
+ raise TypeError("N (= %s) must be a nonnegative integer." % N)
532
+ if N < 0:
533
+ raise TypeError("N (= %s) must be a nonnegative integer." % N)
534
+
535
+ # solve subset sum problem for super-increasing sequence
536
+ candidates = []
537
+ a = self.largest_less_than(N)
538
+ while a is not None:
539
+ candidates.append(a)
540
+ a = self.largest_less_than(N - sum(candidates))
541
+
542
+ lst = list(set(candidates)) # removing any duplicate elements
543
+ if len(lst) != len(candidates):
544
+ return []
545
+ if sum(candidates) == N:
546
+ return candidates
547
+ else:
548
+ return []
549
+
550
+
551
+ def knapsack(seq, binary=True, max=1, value_only=False, solver=None, verbose=0,
552
+ *, integrality_tolerance=1e-3):
553
+ r"""
554
+ Solve the knapsack problem.
555
+
556
+ For more information on the knapsack problem, see the documentation of the
557
+ :mod:`knapsack module <sage.numerical.knapsack>` or the
558
+ :wikipedia:`Knapsack_problem`.
559
+
560
+ INPUT:
561
+
562
+ - ``seq`` -- two different possible types:
563
+
564
+ - A sequence of tuples ``(weight, value, something1, something2,
565
+ ...)``. Note that only the first two coordinates (``weight`` and
566
+ ``values``) will be taken into account. The rest (if any) will be
567
+ ignored. This can be useful if you need to attach some information to
568
+ the items.
569
+
570
+ - A sequence of reals (a value of 1 is assumed).
571
+
572
+ - ``binary`` -- when set to ``True``, an item can be taken 0 or 1 time
573
+ When set to ``False``, an item can be taken any amount of times (while
574
+ staying integer and positive).
575
+
576
+ - ``max`` -- maximum admissible weight
577
+
578
+ - ``value_only`` -- when set to ``True``, only the maximum useful value is
579
+ returned. When set to ``False``, both the maximum useful value and an
580
+ assignment are returned.
581
+
582
+ - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming
583
+ (MILP) solver to be used. If set to ``None``, the default one is used. For
584
+ more information on MILP solvers and which default solver is used, see
585
+ the method
586
+ :meth:`solve <sage.numerical.mip.MixedIntegerLinearProgram.solve>`
587
+ of the class
588
+ :class:`MixedIntegerLinearProgram <sage.numerical.mip.MixedIntegerLinearProgram>`.
589
+
590
+ - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set
591
+ to 0 by default, which means quiet.
592
+
593
+ - ``integrality_tolerance`` -- parameter for use with MILP solvers over an
594
+ inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`
595
+
596
+ OUTPUT:
597
+
598
+ If ``value_only`` is set to ``True``, only the maximum useful value is
599
+ returned. Else (the default), the function returns a pair ``[value,list]``,
600
+ where ``list`` can be of two types according to the type of ``seq``:
601
+
602
+ - The list of tuples `(w_i, u_i, ...)` occurring in the solution.
603
+
604
+ - A list of reals where each real is repeated the number of times it is
605
+ taken into the solution.
606
+
607
+ EXAMPLES:
608
+
609
+ If your knapsack problem is composed of three items ``(weight, value)``
610
+ defined by ``(1,2), (1.5,1), (0.5,3)``, and a bag of maximum weight `2`, you
611
+ can easily solve it this way::
612
+
613
+ sage: from sage.numerical.knapsack import knapsack
614
+ sage: knapsack( [(1,2), (1.5,1), (0.5,3)], max=2)
615
+ [5.0, [(1, 2), (0.500000000000000, 3)]]
616
+
617
+ sage: knapsack( [(1,2), (1.5,1), (0.5,3)], max=2, value_only=True)
618
+ 5.0
619
+
620
+ Besides weight and value, you may attach any data to the items::
621
+
622
+ sage: from sage.numerical.knapsack import knapsack
623
+ sage: knapsack( [(1, 2, 'spam'), (0.5, 3, 'a', 'lot')])
624
+ [3.0, [(0.500000000000000, 3, 'a', 'lot')]]
625
+
626
+ In the case where all the values (usefulness) of the items are equal to one,
627
+ you do not need embarrass yourself with the second values, and you can just
628
+ type for items `(1,1), (1.5,1), (0.5,1)` the command::
629
+
630
+ sage: from sage.numerical.knapsack import knapsack
631
+ sage: knapsack([1,1.5,0.5], max=2, value_only=True)
632
+ 2.0
633
+ """
634
+ reals = not isinstance(seq[0], tuple)
635
+ if reals:
636
+ seq = [(x,1) for x in seq]
637
+
638
+ from sage.numerical.mip import MixedIntegerLinearProgram
639
+ from sage.rings.integer_ring import ZZ
640
+
641
+ p = MixedIntegerLinearProgram(solver=solver, maximization=True)
642
+
643
+ if binary:
644
+ present = p.new_variable(binary=True)
645
+ else:
646
+ present = p.new_variable(integer=True)
647
+
648
+ p.set_objective(p.sum([present[i] * seq[i][1] for i in range(len(seq))]))
649
+ p.add_constraint(p.sum([present[i] * seq[i][0] for i in range(len(seq))]), max=max)
650
+
651
+ if value_only:
652
+ return p.solve(objective_only=True, log=verbose)
653
+
654
+ else:
655
+ objective = p.solve(log=verbose)
656
+ present = p.get_values(present, convert=ZZ, tolerance=integrality_tolerance)
657
+
658
+ val = []
659
+
660
+ if reals:
661
+ [val.extend([seq[i][0]] * present[i]) for i in range(len(seq))]
662
+ else:
663
+ [val.extend([seq[i]] * present[i]) for i in range(len(seq))]
664
+
665
+ return [objective,val]
@@ -0,0 +1,31 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ from sage.structure.parent cimport Parent, Parent_richcmp_element_without_coercion
3
+ from sage.structure.element cimport ModuleElement, RingElement, Element
4
+
5
+ cpdef is_LinearFunction(x)
6
+
7
+ cdef class LinearFunctionOrConstraint(ModuleElement):
8
+ pass
9
+
10
+ cdef class LinearFunctionsParent_class(Parent):
11
+ cpdef _element_constructor_(self, x)
12
+ cpdef _coerce_map_from_(self, R)
13
+ cdef public _multiplication_symbol
14
+
15
+ cdef class LinearFunction(LinearFunctionOrConstraint):
16
+ cdef dict _f
17
+ cpdef _add_(self, other)
18
+ cpdef iteritems(self)
19
+ cpdef _acted_upon_(self, x, bint self_on_left)
20
+ cpdef is_zero(self)
21
+ cpdef equals(LinearFunction left, LinearFunction right)
22
+
23
+ cdef class LinearConstraintsParent_class(Parent):
24
+ cdef LinearFunctionsParent_class _LF
25
+ cpdef _element_constructor_(self, left, right=?, equality=?)
26
+ cpdef _coerce_map_from_(self, R)
27
+
28
+ cdef class LinearConstraint(LinearFunctionOrConstraint):
29
+ cdef bint equality
30
+ cdef list constraints
31
+ cpdef equals(LinearConstraint left, LinearConstraint right)