passagemath-polyhedra 10.6.31rc3__cp314-cp314-macosx_13_0_arm64.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 (205) hide show
  1. passagemath_polyhedra-10.6.31rc3.dist-info/METADATA +368 -0
  2. passagemath_polyhedra-10.6.31rc3.dist-info/METADATA.bak +371 -0
  3. passagemath_polyhedra-10.6.31rc3.dist-info/RECORD +205 -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.dylibs/libgmp.10.dylib +0 -0
  7. sage/all__sagemath_polyhedra.py +50 -0
  8. sage/game_theory/all.py +8 -0
  9. sage/game_theory/catalog.py +6 -0
  10. sage/game_theory/catalog_normal_form_games.py +923 -0
  11. sage/game_theory/cooperative_game.py +844 -0
  12. sage/game_theory/matching_game.py +1181 -0
  13. sage/game_theory/normal_form_game.py +2697 -0
  14. sage/game_theory/parser.py +275 -0
  15. sage/geometry/all__sagemath_polyhedra.py +22 -0
  16. sage/geometry/cone.py +6940 -0
  17. sage/geometry/cone_catalog.py +847 -0
  18. sage/geometry/cone_critical_angles.py +1027 -0
  19. sage/geometry/convex_set.py +1119 -0
  20. sage/geometry/fan.py +3743 -0
  21. sage/geometry/fan_isomorphism.py +389 -0
  22. sage/geometry/fan_morphism.py +1884 -0
  23. sage/geometry/hasse_diagram.py +202 -0
  24. sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
  25. sage/geometry/hyperplane_arrangement/all.py +1 -0
  26. sage/geometry/hyperplane_arrangement/arrangement.py +3895 -0
  27. sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
  28. sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
  29. sage/geometry/hyperplane_arrangement/library.py +825 -0
  30. sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
  31. sage/geometry/hyperplane_arrangement/plot.py +520 -0
  32. sage/geometry/integral_points.py +35 -0
  33. sage/geometry/integral_points_generic_dense.cpython-314-darwin.so +0 -0
  34. sage/geometry/integral_points_generic_dense.pyx +7 -0
  35. sage/geometry/lattice_polytope.py +5894 -0
  36. sage/geometry/linear_expression.py +773 -0
  37. sage/geometry/newton_polygon.py +767 -0
  38. sage/geometry/point_collection.cpython-314-darwin.so +0 -0
  39. sage/geometry/point_collection.pyx +1008 -0
  40. sage/geometry/polyhedral_complex.py +2616 -0
  41. sage/geometry/polyhedron/all.py +8 -0
  42. sage/geometry/polyhedron/backend_cdd.py +460 -0
  43. sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
  44. sage/geometry/polyhedron/backend_field.py +347 -0
  45. sage/geometry/polyhedron/backend_normaliz.py +2503 -0
  46. sage/geometry/polyhedron/backend_number_field.py +168 -0
  47. sage/geometry/polyhedron/backend_polymake.py +765 -0
  48. sage/geometry/polyhedron/backend_ppl.py +582 -0
  49. sage/geometry/polyhedron/base.py +1206 -0
  50. sage/geometry/polyhedron/base0.py +1444 -0
  51. sage/geometry/polyhedron/base1.py +886 -0
  52. sage/geometry/polyhedron/base2.py +812 -0
  53. sage/geometry/polyhedron/base3.py +1845 -0
  54. sage/geometry/polyhedron/base4.py +1262 -0
  55. sage/geometry/polyhedron/base5.py +2700 -0
  56. sage/geometry/polyhedron/base6.py +1741 -0
  57. sage/geometry/polyhedron/base7.py +997 -0
  58. sage/geometry/polyhedron/base_QQ.py +1258 -0
  59. sage/geometry/polyhedron/base_RDF.py +98 -0
  60. sage/geometry/polyhedron/base_ZZ.py +934 -0
  61. sage/geometry/polyhedron/base_mutable.py +215 -0
  62. sage/geometry/polyhedron/base_number_field.py +122 -0
  63. sage/geometry/polyhedron/cdd_file_format.py +155 -0
  64. sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
  65. sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-darwin.so +0 -0
  66. sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
  67. sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
  68. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-darwin.so +0 -0
  69. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
  70. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
  71. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-darwin.so +0 -0
  72. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
  73. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
  74. sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
  75. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-darwin.so +0 -0
  76. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
  77. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
  78. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-darwin.so +0 -0
  79. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
  80. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
  81. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-darwin.so +0 -0
  82. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
  83. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
  84. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-darwin.so +0 -0
  85. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
  86. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
  87. sage/geometry/polyhedron/constructor.py +773 -0
  88. sage/geometry/polyhedron/double_description.py +753 -0
  89. sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
  90. sage/geometry/polyhedron/face.py +1060 -0
  91. sage/geometry/polyhedron/generating_function.py +1810 -0
  92. sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
  93. sage/geometry/polyhedron/library.py +3502 -0
  94. sage/geometry/polyhedron/misc.py +121 -0
  95. sage/geometry/polyhedron/modules/all.py +1 -0
  96. sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
  97. sage/geometry/polyhedron/palp_database.py +447 -0
  98. sage/geometry/polyhedron/parent.py +1279 -0
  99. sage/geometry/polyhedron/plot.py +1986 -0
  100. sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
  101. sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
  102. sage/geometry/polyhedron/representation.py +1723 -0
  103. sage/geometry/pseudolines.py +515 -0
  104. sage/geometry/relative_interior.py +445 -0
  105. sage/geometry/toric_plotter.py +1103 -0
  106. sage/geometry/triangulation/all.py +2 -0
  107. sage/geometry/triangulation/base.cpython-314-darwin.so +0 -0
  108. sage/geometry/triangulation/base.pyx +963 -0
  109. sage/geometry/triangulation/data.h +147 -0
  110. sage/geometry/triangulation/data.pxd +4 -0
  111. sage/geometry/triangulation/element.py +914 -0
  112. sage/geometry/triangulation/functions.h +10 -0
  113. sage/geometry/triangulation/functions.pxd +4 -0
  114. sage/geometry/triangulation/point_configuration.py +2256 -0
  115. sage/geometry/triangulation/triangulations.h +49 -0
  116. sage/geometry/triangulation/triangulations.pxd +7 -0
  117. sage/geometry/voronoi_diagram.py +319 -0
  118. sage/interfaces/all__sagemath_polyhedra.py +1 -0
  119. sage/interfaces/polymake.py +2028 -0
  120. sage/numerical/all.py +13 -0
  121. sage/numerical/all__sagemath_polyhedra.py +11 -0
  122. sage/numerical/backends/all.py +1 -0
  123. sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
  124. sage/numerical/backends/cvxopt_backend.cpython-314-darwin.so +0 -0
  125. sage/numerical/backends/cvxopt_backend.pyx +1006 -0
  126. sage/numerical/backends/cvxopt_backend_test.py +19 -0
  127. sage/numerical/backends/cvxopt_sdp_backend.cpython-314-darwin.so +0 -0
  128. sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
  129. sage/numerical/backends/cvxpy_backend.cpython-314-darwin.so +0 -0
  130. sage/numerical/backends/cvxpy_backend.pxd +41 -0
  131. sage/numerical/backends/cvxpy_backend.pyx +934 -0
  132. sage/numerical/backends/cvxpy_backend_test.py +13 -0
  133. sage/numerical/backends/generic_backend_test.py +24 -0
  134. sage/numerical/backends/interactivelp_backend.cpython-314-darwin.so +0 -0
  135. sage/numerical/backends/interactivelp_backend.pxd +36 -0
  136. sage/numerical/backends/interactivelp_backend.pyx +1231 -0
  137. sage/numerical/backends/interactivelp_backend_test.py +12 -0
  138. sage/numerical/backends/logging_backend.py +391 -0
  139. sage/numerical/backends/matrix_sdp_backend.cpython-314-darwin.so +0 -0
  140. sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
  141. sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
  142. sage/numerical/backends/ppl_backend.cpython-314-darwin.so +0 -0
  143. sage/numerical/backends/ppl_backend.pyx +1126 -0
  144. sage/numerical/backends/ppl_backend_test.py +13 -0
  145. sage/numerical/backends/scip_backend.cpython-314-darwin.so +0 -0
  146. sage/numerical/backends/scip_backend.pxd +22 -0
  147. sage/numerical/backends/scip_backend.pyx +1289 -0
  148. sage/numerical/backends/scip_backend_test.py +13 -0
  149. sage/numerical/interactive_simplex_method.py +5338 -0
  150. sage/numerical/knapsack.py +665 -0
  151. sage/numerical/linear_functions.cpython-314-darwin.so +0 -0
  152. sage/numerical/linear_functions.pxd +31 -0
  153. sage/numerical/linear_functions.pyx +1648 -0
  154. sage/numerical/linear_tensor.py +470 -0
  155. sage/numerical/linear_tensor_constraints.py +448 -0
  156. sage/numerical/linear_tensor_element.cpython-314-darwin.so +0 -0
  157. sage/numerical/linear_tensor_element.pxd +6 -0
  158. sage/numerical/linear_tensor_element.pyx +459 -0
  159. sage/numerical/mip.cpython-314-darwin.so +0 -0
  160. sage/numerical/mip.pxd +40 -0
  161. sage/numerical/mip.pyx +3667 -0
  162. sage/numerical/sdp.cpython-314-darwin.so +0 -0
  163. sage/numerical/sdp.pxd +39 -0
  164. sage/numerical/sdp.pyx +1433 -0
  165. sage/rings/all__sagemath_polyhedra.py +3 -0
  166. sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
  167. sage/rings/polynomial/omega.py +982 -0
  168. sage/schemes/all__sagemath_polyhedra.py +2 -0
  169. sage/schemes/toric/all.py +10 -0
  170. sage/schemes/toric/chow_group.py +1248 -0
  171. sage/schemes/toric/divisor.py +2082 -0
  172. sage/schemes/toric/divisor_class.cpython-314-darwin.so +0 -0
  173. sage/schemes/toric/divisor_class.pyx +322 -0
  174. sage/schemes/toric/fano_variety.py +1606 -0
  175. sage/schemes/toric/homset.py +650 -0
  176. sage/schemes/toric/ideal.py +451 -0
  177. sage/schemes/toric/library.py +1322 -0
  178. sage/schemes/toric/morphism.py +1958 -0
  179. sage/schemes/toric/points.py +1032 -0
  180. sage/schemes/toric/sheaf/all.py +1 -0
  181. sage/schemes/toric/sheaf/constructor.py +302 -0
  182. sage/schemes/toric/sheaf/klyachko.py +921 -0
  183. sage/schemes/toric/toric_subscheme.py +905 -0
  184. sage/schemes/toric/variety.py +3460 -0
  185. sage/schemes/toric/weierstrass.py +1078 -0
  186. sage/schemes/toric/weierstrass_covering.py +457 -0
  187. sage/schemes/toric/weierstrass_higher.py +288 -0
  188. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
  189. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
  190. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
  191. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
  192. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
  193. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
  194. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
  195. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
  196. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
  197. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
  198. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
  199. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
  200. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
  201. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
  202. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
  203. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
  204. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
  205. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
@@ -0,0 +1,844 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ """
3
+ Co-operative Games With Finite Players
4
+
5
+ This module implements a class for a characteristic function cooperative
6
+ game. Methods to calculate the Shapley value (a fair way of sharing
7
+ common resources: see [CEW2011]_) as well as test properties of the game
8
+ (monotonicity, superadditivity) are also included.
9
+
10
+ AUTHORS:
11
+
12
+ - James Campbell and Vince Knight (06-2014): Original version
13
+ """
14
+
15
+ # ****************************************************************************
16
+ # Copyright (C) 2014 James Campbell james.campbell@tanti.org.uk
17
+ #
18
+ # This program is free software: you can redistribute it and/or modify
19
+ # it under the terms of the GNU General Public License as published by
20
+ # the Free Software Foundation, either version 3 of the License, or
21
+ # (at your option) any later version.
22
+ # https://www.gnu.org/licenses/
23
+ # ****************************************************************************
24
+ from itertools import permutations, combinations
25
+ from sage.combinat.subset import powerset
26
+ from sage.rings.integer import Integer
27
+ from sage.structure.sage_object import SageObject
28
+
29
+
30
+ class CooperativeGame(SageObject):
31
+ r"""
32
+ An object representing a co-operative game. Primarily used to compute the
33
+ Shapley value, but can also provide other information.
34
+
35
+ INPUT:
36
+
37
+ - ``characteristic_function`` -- dictionary containing all possible
38
+ sets of players:
39
+
40
+ * key - each set must be entered as a tuple.
41
+ * value - a real number representing each set of players contribution
42
+
43
+ EXAMPLES:
44
+
45
+ The type of game that is currently implemented is referred to as a
46
+ Characteristic function game. This is a game on a set of players
47
+ `\Omega` that is defined by a value function `v : C \to \RR` where
48
+ `C = 2^{\Omega}` is the set of all coalitions of players.
49
+ Let `N := |\Omega|`.
50
+ An example of such a game is shown below:
51
+
52
+ .. MATH::
53
+
54
+ v(c) = \begin{cases}
55
+ 0 &\text{if } c = \emptyset, \\
56
+ 6 &\text{if } c = \{1\}, \\
57
+ 12 &\text{if } c = \{2\}, \\
58
+ 42 &\text{if } c = \{3\}, \\
59
+ 12 &\text{if } c = \{1,2\}, \\
60
+ 42 &\text{if } c = \{1,3\}, \\
61
+ 42 &\text{if } c = \{2,3\}, \\
62
+ 42 &\text{if } c = \{1,2,3\}. \\
63
+ \end{cases}
64
+
65
+ The function `v` can be thought of as a record of contribution of
66
+ individuals and coalitions of individuals. Of interest, becomes how to
67
+ fairly share the value of the grand coalition (`\Omega`)? This class
68
+ allows for such an answer to be formulated by calculating the Shapley
69
+ value of the game.
70
+
71
+ Basic examples of how to implement a co-operative game. These functions
72
+ will be used repeatedly in other examples. ::
73
+
74
+ sage: integer_function = {(): 0,
75
+ ....: (1,): 6,
76
+ ....: (2,): 12,
77
+ ....: (3,): 42,
78
+ ....: (1, 2,): 12,
79
+ ....: (1, 3,): 42,
80
+ ....: (2, 3,): 42,
81
+ ....: (1, 2, 3,): 42}
82
+ sage: integer_game = CooperativeGame(integer_function)
83
+
84
+ We can also use strings instead of numbers. ::
85
+
86
+ sage: letter_function = {(): 0,
87
+ ....: ('A',): 6,
88
+ ....: ('B',): 12,
89
+ ....: ('C',): 42,
90
+ ....: ('A', 'B',): 12,
91
+ ....: ('A', 'C',): 42,
92
+ ....: ('B', 'C',): 42,
93
+ ....: ('A', 'B', 'C',): 42}
94
+ sage: letter_game = CooperativeGame(letter_function)
95
+
96
+ Please note that keys should be tuples. ``'1, 2, 3'`` is not a valid key,
97
+ neither is ``123``. The correct input would be ``(1, 2, 3)``. Similarly,
98
+ for coalitions containing a single element the bracket notation (which
99
+ tells Sage that it is a tuple) must be used. So ``(1)``, ``(1,)`` are
100
+ correct however simply inputting `1` is not.
101
+
102
+ Characteristic function games can be of various types.
103
+
104
+ A characteristic function game `G = (N, v)` is monotone if it satisfies
105
+ `v(C_2) \geq v(C_1)` for all `C_1 \subseteq C_2`. A characteristic
106
+ function game `G = (N, v)` is superadditive if it satisfies
107
+ `v(C_1 \cup C_2) \geq v(C_1) + v(C_2)` for all `C_1, C_2 \subseteq 2^{\Omega}` such
108
+ that `C_1 \cap C_2 = \emptyset`.
109
+
110
+ We can test if a game is monotonic or superadditive. ::
111
+
112
+ sage: letter_game.is_monotone()
113
+ True
114
+ sage: letter_game.is_superadditive()
115
+ False
116
+
117
+ Instances have a basic representation that will display basic information
118
+ about the game::
119
+
120
+ sage: letter_game
121
+ A 3 player co-operative game
122
+
123
+ It can be shown that the "fair" payoff vector, referred to as the
124
+ Shapley value is given by the following formula:
125
+
126
+ .. MATH::
127
+
128
+ \phi_i(G) = \frac{1}{N!} \sum_{\pi\in\Pi_n} \Delta_{\pi}^G(i),
129
+
130
+ where the summation is over the permutations of the players and the
131
+ marginal contributions of a player for a given permutation is given as:
132
+
133
+ .. MATH::
134
+
135
+ \Delta_{\pi}^G(i) = v\bigl( S_{\pi}(i) \cup \{i\} \bigr)
136
+ - v\bigl( S_{\pi}(i) \bigr)
137
+
138
+ where `S_{\pi}(i)` is the set of predecessors of `i` in `\pi`, i.e.
139
+ `S_{\pi}(i) = \{ j \mid \pi(i) > \pi(j) \}` (or the number of inversions
140
+ of the form `(i, j)`).
141
+
142
+ This payoff vector is "fair" in that it has a collection of properties
143
+ referred to as: efficiency, symmetry, additivity and Null player.
144
+ Some of these properties are considered in this documentation (and tests
145
+ are implemented in the class) but for a good overview see [CEW2011]_.
146
+
147
+ Note ([MSZ2013]_) that an equivalent formula for the Shapley value is given by:
148
+
149
+ .. MATH::
150
+
151
+ \phi_i(G) = \sum_{S \subseteq \Omega} \sum_{p \in S}
152
+ \frac{(|S|-1)!(N-|S|)!}{N!} \bigl( v(S) - v(S \setminus \{p\}) \bigr)
153
+ = \sum_{S \subseteq \Omega} \sum_{p \in S}
154
+ \frac{1}{|S|\binom{N}{|S|}} \bigl( v(S) - v(S \setminus \{p\}) \bigr).
155
+
156
+ This later formulation is implemented in Sage and
157
+ requires `2^N-1` calculations instead of `N!`.
158
+
159
+ To compute the Shapley value in Sage is simple::
160
+
161
+ sage: letter_game.shapley_value()
162
+ {'A': 2, 'B': 5, 'C': 35}
163
+
164
+ The following example implements a (trivial) 10 player characteristic
165
+ function game with `v(c) = |c|` for all `c \in 2^{\Omega}`.
166
+
167
+ ::
168
+
169
+ sage: def simple_characteristic_function(N):
170
+ ....: return {tuple(coalition) : len(coalition)
171
+ ....: for coalition in subsets(range(N))}
172
+ sage: g = CooperativeGame(simple_characteristic_function(10))
173
+ sage: g.shapley_value()
174
+ {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1}
175
+
176
+ For very large games it might be worth taking advantage of the particular
177
+ problem structure to calculate the Shapley value and there are also
178
+ various approximation approaches to obtaining the Shapley value of a game
179
+ (see [SWJ2008]_ for one such example). Implementing these would be a
180
+ worthwhile development For more information about the computational
181
+ complexity of calculating the Shapley value see [XP1994]_.
182
+
183
+ We can test 3 basic properties of any payoff vector `\lambda`.
184
+ The Shapley value (described above) is known to be the unique
185
+ payoff vector that satisfies these and 1 other property
186
+ not implemented here (additivity). They are:
187
+
188
+ * Efficiency - `\sum_{i=1}^N \lambda_i = v(\Omega)`
189
+ In other words, no value of the total coalition is lost.
190
+
191
+ * The nullplayer property - If there exists an `i` such that
192
+ `v(C \cup i) = v(C)` for all `C \in 2^{\Omega}` then, `\lambda_i = 0`.
193
+ In other words: if a player does not contribute to any coalition then
194
+ that player should receive no payoff.
195
+
196
+ * Symmetry property - If `v(C \cup i) = v(C \cup j)` for all
197
+ `C \in 2^{\Omega} \setminus \{i,j\}`, then `x_i = x_j`.
198
+ If players contribute symmetrically then they should get the same
199
+ payoff::
200
+
201
+ sage: payoff_vector = letter_game.shapley_value()
202
+ sage: letter_game.is_efficient(payoff_vector)
203
+ True
204
+ sage: letter_game.nullplayer(payoff_vector)
205
+ True
206
+ sage: letter_game.is_symmetric(payoff_vector)
207
+ True
208
+
209
+ Any payoff vector can be passed to the game and these properties
210
+ can once again be tested::
211
+
212
+ sage: payoff_vector = {'A': 0, 'C': 35, 'B': 3}
213
+ sage: letter_game.is_efficient(payoff_vector)
214
+ False
215
+ sage: letter_game.nullplayer(payoff_vector)
216
+ True
217
+ sage: letter_game.is_symmetric(payoff_vector)
218
+ True
219
+
220
+ TESTS:
221
+
222
+ Check that the order within a key does not affect other functions::
223
+
224
+ sage: letter_function = {(): 0,
225
+ ....: ('A',): 6,
226
+ ....: ('B',): 12,
227
+ ....: ('C',): 42,
228
+ ....: ('A', 'B',): 12,
229
+ ....: ('C', 'A',): 42,
230
+ ....: ('B', 'C',): 42,
231
+ ....: ('B', 'A', 'C',): 42}
232
+ sage: letter_game = CooperativeGame(letter_function)
233
+ sage: letter_game.shapley_value()
234
+ {'A': 2, 'B': 5, 'C': 35}
235
+ sage: letter_game.is_monotone()
236
+ True
237
+ sage: letter_game.is_superadditive()
238
+ False
239
+ sage: letter_game.is_efficient({'A': 2, 'C': 35, 'B': 5})
240
+ True
241
+ sage: letter_game.nullplayer({'A': 2, 'C': 35, 'B': 5})
242
+ True
243
+ sage: letter_game.is_symmetric({'A': 2, 'C': 35, 'B': 5})
244
+ True
245
+
246
+ Any payoff vector can be passed to the game and these properties can once
247
+ again be tested. ::
248
+
249
+ sage: letter_game.is_efficient({'A': 0, 'C': 35, 'B': 3})
250
+ False
251
+ sage: letter_game.nullplayer({'A': 0, 'C': 35, 'B': 3})
252
+ True
253
+ sage: letter_game.is_symmetric({'A': 0, 'C': 35, 'B': 3})
254
+ True
255
+ """
256
+ def __init__(self, characteristic_function):
257
+ r"""
258
+ Initialize a co-operative game and checks the inputs.
259
+
260
+ TESTS:
261
+
262
+ An attempt to construct a game from an integer::
263
+
264
+ sage: int_game = CooperativeGame(4)
265
+ Traceback (most recent call last):
266
+ ...
267
+ TypeError: characteristic function must be a dictionary
268
+
269
+ This test checks that an incorrectly entered singularly tuple will be
270
+ changed into a tuple. In this case ``(1)`` becomes ``(1,)``::
271
+
272
+ sage: tuple_function = {(): 0,
273
+ ....: (1): 6,
274
+ ....: (2,): 12,
275
+ ....: (3,): 42,
276
+ ....: (1, 2,): 12,
277
+ ....: (1, 3,): 42,
278
+ ....: (2, 3,): 42,
279
+ ....: (1, 2, 3,): 42}
280
+ sage: tuple_game = CooperativeGame(tuple_function)
281
+
282
+ This test checks that if a key is not a tuple an error is raised::
283
+
284
+ sage: error_function = {(): 0,
285
+ ....: (1,): 6,
286
+ ....: (2,): 12,
287
+ ....: (3,): 42,
288
+ ....: 12: 12,
289
+ ....: (1, 3,): 42,
290
+ ....: (2, 3,): 42,
291
+ ....: (1, 2, 3,): 42}
292
+ sage: error_game = CooperativeGame(error_function)
293
+ Traceback (most recent call last):
294
+ ...
295
+ TypeError: key must be a tuple
296
+
297
+ A test to ensure that the characteristic function is the power
298
+ set of the grand coalition (ie all possible sub-coalitions)::
299
+
300
+ sage: incorrect_function = {(): 0,
301
+ ....: (1,): 6,
302
+ ....: (2,): 12,
303
+ ....: (3,): 42,
304
+ ....: (1, 2, 3,): 42}
305
+ sage: incorrect_game = CooperativeGame(incorrect_function)
306
+ Traceback (most recent call last):
307
+ ...
308
+ ValueError: characteristic function must be the power set
309
+ """
310
+ if not isinstance(characteristic_function, dict):
311
+ raise TypeError("characteristic function must be a dictionary")
312
+
313
+ self.ch_f = characteristic_function
314
+ for key in list(self.ch_f):
315
+ if len(str(key)) == 1 and not isinstance(key, tuple):
316
+ self.ch_f[(key,)] = self.ch_f.pop(key)
317
+ elif not isinstance(key, tuple):
318
+ raise TypeError("key must be a tuple")
319
+
320
+ for key in list(self.ch_f):
321
+ sortedkey = tuple(sorted(key))
322
+ self.ch_f[sortedkey] = self.ch_f.pop(key)
323
+
324
+ self.player_list = max(characteristic_function, key=len)
325
+ for coalition in powerset(self.player_list):
326
+ if tuple(sorted(coalition)) not in self.ch_f:
327
+ raise ValueError("characteristic function must be the power set")
328
+
329
+ self.number_players = len(self.player_list)
330
+
331
+ def shapley_value(self):
332
+ r"""
333
+ Return the Shapley value for ``self``.
334
+
335
+ The Shapley value is the "fair" payoff vector and
336
+ is computed by the following formula:
337
+
338
+ .. MATH::
339
+
340
+ \phi_i(G) = \sum_{S \subseteq \Omega} \sum_{p \in S}
341
+ \frac{1}{|S|\binom{N}{|S|}}
342
+ \bigl( v(S) - v(S \setminus \{p\}) \bigr).
343
+
344
+ EXAMPLES:
345
+
346
+ A typical example of computing the Shapley value::
347
+
348
+ sage: integer_function = {(): 0,
349
+ ....: (1,): 6,
350
+ ....: (2,): 12,
351
+ ....: (3,): 42,
352
+ ....: (1, 2,): 12,
353
+ ....: (1, 3,): 42,
354
+ ....: (2, 3,): 42,
355
+ ....: (1, 2, 3,): 42}
356
+ sage: integer_game = CooperativeGame(integer_function)
357
+ sage: integer_game.player_list
358
+ (1, 2, 3)
359
+ sage: integer_game.shapley_value()
360
+ {1: 2, 2: 5, 3: 35}
361
+
362
+ A longer example of the Shapley value::
363
+
364
+ sage: long_function = {(): 0,
365
+ ....: (1,): 0,
366
+ ....: (2,): 0,
367
+ ....: (3,): 0,
368
+ ....: (4,): 0,
369
+ ....: (1, 2): 0,
370
+ ....: (1, 3): 0,
371
+ ....: (1, 4): 0,
372
+ ....: (2, 3): 0,
373
+ ....: (2, 4): 0,
374
+ ....: (3, 4): 0,
375
+ ....: (1, 2, 3): 0,
376
+ ....: (1, 2, 4): 45,
377
+ ....: (1, 3, 4): 40,
378
+ ....: (2, 3, 4): 0,
379
+ ....: (1, 2, 3, 4): 65}
380
+ sage: long_game = CooperativeGame(long_function)
381
+ sage: long_game.shapley_value()
382
+ {1: 70/3, 2: 10, 3: 25/3, 4: 70/3}
383
+ """
384
+ payoff_vector = {}
385
+ n = Integer(len(self.player_list))
386
+ for player in self.player_list:
387
+ weighted_contribution = 0
388
+ for coalition in powerset(self.player_list):
389
+ if coalition: # If non-empty
390
+ k = Integer(len(coalition))
391
+ weight = 1 / (n.binomial(k) * k)
392
+ t = tuple(p for p in coalition if p != player)
393
+ weighted_contribution += weight * (self.ch_f[tuple(coalition)]
394
+ - self.ch_f[t])
395
+ payoff_vector[player] = weighted_contribution
396
+
397
+ return payoff_vector
398
+
399
+ def is_monotone(self):
400
+ r"""
401
+ Return ``True`` if ``self`` is monotonic.
402
+
403
+ A game `G = (N, v)` is monotonic if it satisfies
404
+ `v(C_2) \geq v(C_1)` for all `C_1 \subseteq C_2`.
405
+
406
+ EXAMPLES:
407
+
408
+ A simple game that is monotone::
409
+
410
+ sage: integer_function = {(): 0,
411
+ ....: (1,): 6,
412
+ ....: (2,): 12,
413
+ ....: (3,): 42,
414
+ ....: (1, 2,): 12,
415
+ ....: (1, 3,): 42,
416
+ ....: (2, 3,): 42,
417
+ ....: (1, 2, 3,): 42}
418
+ sage: integer_game = CooperativeGame(integer_function)
419
+ sage: integer_game.is_monotone()
420
+ True
421
+
422
+ An example when the game is not monotone::
423
+
424
+ sage: integer_function = {(): 0,
425
+ ....: (1,): 6,
426
+ ....: (2,): 12,
427
+ ....: (3,): 42,
428
+ ....: (1, 2,): 10,
429
+ ....: (1, 3,): 42,
430
+ ....: (2, 3,): 42,
431
+ ....: (1, 2, 3,): 42}
432
+ sage: integer_game = CooperativeGame(integer_function)
433
+ sage: integer_game.is_monotone()
434
+ False
435
+
436
+ An example on a longer game::
437
+
438
+ sage: long_function = {(): 0,
439
+ ....: (1,): 0,
440
+ ....: (2,): 0,
441
+ ....: (3,): 0,
442
+ ....: (4,): 0,
443
+ ....: (1, 2): 0,
444
+ ....: (1, 3): 0,
445
+ ....: (1, 4): 0,
446
+ ....: (2, 3): 0,
447
+ ....: (2, 4): 0,
448
+ ....: (3, 4): 0,
449
+ ....: (1, 2, 3): 0,
450
+ ....: (1, 2, 4): 45,
451
+ ....: (1, 3, 4): 40,
452
+ ....: (2, 3, 4): 0,
453
+ ....: (1, 2, 3, 4): 65}
454
+ sage: long_game = CooperativeGame(long_function)
455
+ sage: long_game.is_monotone()
456
+ True
457
+ """
458
+ return not any(set(p1) <= set(p2) and self.ch_f[p1] > self.ch_f[p2]
459
+ for p1, p2 in permutations(self.ch_f.keys(), 2))
460
+
461
+ def is_superadditive(self):
462
+ r"""
463
+ Return ``True`` if ``self`` is superadditive.
464
+
465
+ A characteristic function game `G = (N, v)` is superadditive
466
+ if it satisfies `v(C_1 \cup C_2) \geq v(C_1) + v(C_2)` for
467
+ all `C_1, C_2 \subseteq 2^{\Omega}` such that `C_1 \cap C_2
468
+ = \emptyset`.
469
+
470
+ EXAMPLES:
471
+
472
+ An example that is not superadditive::
473
+
474
+ sage: integer_function = {(): 0,
475
+ ....: (1,): 6,
476
+ ....: (2,): 12,
477
+ ....: (3,): 42,
478
+ ....: (1, 2,): 12,
479
+ ....: (1, 3,): 42,
480
+ ....: (2, 3,): 42,
481
+ ....: (1, 2, 3,): 42}
482
+ sage: integer_game = CooperativeGame(integer_function)
483
+ sage: integer_game.is_superadditive()
484
+ False
485
+
486
+ An example that is superadditive::
487
+
488
+ sage: A_function = {(): 0,
489
+ ....: (1,): 6,
490
+ ....: (2,): 12,
491
+ ....: (3,): 42,
492
+ ....: (1, 2,): 18,
493
+ ....: (1, 3,): 48,
494
+ ....: (2, 3,): 55,
495
+ ....: (1, 2, 3,): 80}
496
+ sage: A_game = CooperativeGame(A_function)
497
+ sage: A_game.is_superadditive()
498
+ True
499
+
500
+ An example with a longer game that is superadditive::
501
+
502
+ sage: long_function = {(): 0,
503
+ ....: (1,): 0,
504
+ ....: (2,): 0,
505
+ ....: (3,): 0,
506
+ ....: (4,): 0,
507
+ ....: (1, 2): 0,
508
+ ....: (1, 3): 0,
509
+ ....: (1, 4): 0,
510
+ ....: (2, 3): 0,
511
+ ....: (2, 4): 0,
512
+ ....: (3, 4): 0,
513
+ ....: (1, 2, 3): 0,
514
+ ....: (1, 2, 4): 45,
515
+ ....: (1, 3, 4): 40,
516
+ ....: (2, 3, 4): 0,
517
+ ....: (1, 2, 3, 4): 65}
518
+ sage: long_game = CooperativeGame(long_function)
519
+ sage: long_game.is_superadditive()
520
+ True
521
+
522
+ An example with a longer game that is not::
523
+
524
+ sage: long_function = {(): 0,
525
+ ....: (1,): 0,
526
+ ....: (2,): 0,
527
+ ....: (3,): 55,
528
+ ....: (4,): 0,
529
+ ....: (1, 2): 0,
530
+ ....: (1, 3): 0,
531
+ ....: (1, 4): 0,
532
+ ....: (2, 3): 0,
533
+ ....: (2, 4): 0,
534
+ ....: (3, 4): 0,
535
+ ....: (1, 2, 3): 0,
536
+ ....: (1, 2, 4): 45,
537
+ ....: (1, 3, 4): 40,
538
+ ....: (2, 3, 4): 0,
539
+ ....: (1, 2, 3, 4): 85}
540
+ sage: long_game = CooperativeGame(long_function)
541
+ sage: long_game.is_superadditive()
542
+ False
543
+ """
544
+ sets = self.ch_f.keys()
545
+ for p1, p2 in combinations(sets, 2):
546
+ if not (set(p1) & set(p2)):
547
+ union = tuple(sorted(set(p1) | set(p2)))
548
+ if self.ch_f[union] < self.ch_f[p1] + self.ch_f[p2]:
549
+ return False
550
+ return True
551
+
552
+ def _repr_(self):
553
+ r"""
554
+ Return a concise description of ``self``.
555
+
556
+ EXAMPLES::
557
+
558
+ sage: letter_function = {(): 0,
559
+ ....: ('A',): 6,
560
+ ....: ('B',): 12,
561
+ ....: ('C',): 42,
562
+ ....: ('A', 'B',): 12,
563
+ ....: ('A', 'C',): 42,
564
+ ....: ('B', 'C',): 42,
565
+ ....: ('A', 'B', 'C',): 42}
566
+ sage: letter_game = CooperativeGame(letter_function)
567
+ sage: letter_game
568
+ A 3 player co-operative game
569
+ """
570
+ return "A {} player co-operative game".format(self.number_players)
571
+
572
+ def _latex_(self):
573
+ r"""
574
+ Return the LaTeX code representing the characteristic function.
575
+
576
+ EXAMPLES::
577
+
578
+ sage: letter_function = {(): 0,
579
+ ....: ('A',): 6,
580
+ ....: ('B',): 12,
581
+ ....: ('C',): 42,
582
+ ....: ('A', 'B',): 12,
583
+ ....: ('A', 'C',): 42,
584
+ ....: ('B', 'C',): 42,
585
+ ....: ('A', 'B', 'C',): 42}
586
+ sage: letter_game = CooperativeGame(letter_function)
587
+ sage: latex(letter_game)
588
+ v(c) = \begin{cases}
589
+ 0, & \text{if } c = \emptyset \\
590
+ 6, & \text{if } c = \{A\} \\
591
+ 12, & \text{if } c = \{B\} \\
592
+ 42, & \text{if } c = \{C\} \\
593
+ 12, & \text{if } c = \{A, B\} \\
594
+ 42, & \text{if } c = \{A, C\} \\
595
+ 42, & \text{if } c = \{B, C\} \\
596
+ 42, & \text{if } c = \{A, B, C\} \\
597
+ \end{cases}
598
+ """
599
+ cf = self.ch_f
600
+ output = "v(c) = \\begin{cases}\n"
601
+ for key, val in sorted(cf.items(), key=lambda kv: (len(kv[0]), kv[0])):
602
+ if not key: # == ()
603
+ coalition = "\\emptyset"
604
+ else:
605
+ coalition = "\\{" + ", ".join(str(player) for player in key) + "\\}"
606
+ output += "{}, & \\text{{if }} c = {} \\\\\n".format(val, coalition)
607
+ output += "\\end{cases}"
608
+ return output
609
+
610
+ def is_efficient(self, payoff_vector):
611
+ r"""
612
+ Return ``True`` if ``payoff_vector`` is efficient.
613
+
614
+ A payoff vector `v` is efficient if
615
+ `\sum_{i=1}^N \lambda_i = v(\Omega)`;
616
+ in other words, no value of the total coalition is lost.
617
+
618
+ INPUT:
619
+
620
+ - ``payoff_vector`` -- dictionary where the key is the player
621
+ and the value is their payoff
622
+
623
+ EXAMPLES:
624
+
625
+ An efficient payoff vector::
626
+
627
+ sage: letter_function = {(): 0,
628
+ ....: ('A',): 6,
629
+ ....: ('B',): 12,
630
+ ....: ('C',): 42,
631
+ ....: ('A', 'B',): 12,
632
+ ....: ('A', 'C',): 42,
633
+ ....: ('B', 'C',): 42,
634
+ ....: ('A', 'B', 'C',): 42}
635
+ sage: letter_game = CooperativeGame(letter_function)
636
+ sage: letter_game.is_efficient({'A': 14, 'B': 14, 'C': 14})
637
+ True
638
+
639
+ sage: letter_function = {(): 0,
640
+ ....: ('A',): 6,
641
+ ....: ('B',): 12,
642
+ ....: ('C',): 42,
643
+ ....: ('A', 'B',): 12,
644
+ ....: ('A', 'C',): 42,
645
+ ....: ('B', 'C',): 42,
646
+ ....: ('A', 'B', 'C',): 42}
647
+ sage: letter_game = CooperativeGame(letter_function)
648
+ sage: letter_game.is_efficient({'A': 10, 'B': 14, 'C': 14})
649
+ False
650
+
651
+ A longer example::
652
+
653
+ sage: long_function = {(): 0,
654
+ ....: (1,): 0,
655
+ ....: (2,): 0,
656
+ ....: (3,): 0,
657
+ ....: (4,): 0,
658
+ ....: (1, 2): 0,
659
+ ....: (1, 3): 0,
660
+ ....: (1, 4): 0,
661
+ ....: (2, 3): 0,
662
+ ....: (2, 4): 0,
663
+ ....: (3, 4): 0,
664
+ ....: (1, 2, 3): 0,
665
+ ....: (1, 2, 4): 45,
666
+ ....: (1, 3, 4): 40,
667
+ ....: (2, 3, 4): 0,
668
+ ....: (1, 2, 3, 4): 65}
669
+ sage: long_game = CooperativeGame(long_function)
670
+ sage: long_game.is_efficient({1: 20, 2: 20, 3: 5, 4: 20})
671
+ True
672
+ """
673
+ pl = tuple(sorted(self.player_list))
674
+ return sum(payoff_vector.values()) == self.ch_f[pl]
675
+
676
+ def nullplayer(self, payoff_vector):
677
+ r"""
678
+ Return ``True`` if ``payoff_vector`` possesses the nullplayer
679
+ property.
680
+
681
+ A payoff vector `v` has the nullplayer property if there exists
682
+ an `i` such that `v(C \cup i) = v(C)` for all `C \in 2^{\Omega}`
683
+ then, `\lambda_i = 0`. In other words: if a player does not
684
+ contribute to any coalition then that player should receive no payoff.
685
+
686
+ INPUT:
687
+
688
+ - ``payoff_vector`` -- dictionary where the key is the player
689
+ and the value is their payoff
690
+
691
+ EXAMPLES:
692
+
693
+ A payoff vector that returns ``True``::
694
+
695
+ sage: letter_function = {(): 0,
696
+ ....: ('A',): 0,
697
+ ....: ('B',): 12,
698
+ ....: ('C',): 42,
699
+ ....: ('A', 'B',): 12,
700
+ ....: ('A', 'C',): 42,
701
+ ....: ('B', 'C',): 42,
702
+ ....: ('A', 'B', 'C',): 42}
703
+ sage: letter_game = CooperativeGame(letter_function)
704
+ sage: letter_game.nullplayer({'A': 0, 'B': 14, 'C': 14})
705
+ True
706
+
707
+ A payoff vector that returns ``False``::
708
+
709
+ sage: A_function = {(): 0,
710
+ ....: (1,): 0,
711
+ ....: (2,): 12,
712
+ ....: (3,): 42,
713
+ ....: (1, 2,): 12,
714
+ ....: (1, 3,): 42,
715
+ ....: (2, 3,): 55,
716
+ ....: (1, 2, 3,): 55}
717
+ sage: A_game = CooperativeGame(A_function)
718
+ sage: A_game.nullplayer({1: 10, 2: 10, 3: 25})
719
+ False
720
+
721
+ A longer example for nullplayer::
722
+
723
+ sage: long_function = {(): 0,
724
+ ....: (1,): 0,
725
+ ....: (2,): 0,
726
+ ....: (3,): 0,
727
+ ....: (4,): 0,
728
+ ....: (1, 2): 0,
729
+ ....: (1, 3): 0,
730
+ ....: (1, 4): 0,
731
+ ....: (2, 3): 0,
732
+ ....: (2, 4): 0,
733
+ ....: (3, 4): 0,
734
+ ....: (1, 2, 3): 0,
735
+ ....: (1, 2, 4): 45,
736
+ ....: (1, 3, 4): 40,
737
+ ....: (2, 3, 4): 0,
738
+ ....: (1, 2, 3, 4): 65}
739
+ sage: long_game = CooperativeGame(long_function)
740
+ sage: long_game.nullplayer({1: 20, 2: 20, 3: 5, 4: 20})
741
+ True
742
+
743
+ TESTS:
744
+
745
+ Checks that the function is going through all players::
746
+
747
+ sage: A_function = {(): 0,
748
+ ....: (1,): 42,
749
+ ....: (2,): 12,
750
+ ....: (3,): 0,
751
+ ....: (1, 2,): 55,
752
+ ....: (1, 3,): 42,
753
+ ....: (2, 3,): 12,
754
+ ....: (1, 2, 3,): 55}
755
+ sage: A_game = CooperativeGame(A_function)
756
+ sage: A_game.nullplayer({1: 10, 2: 10, 3: 25})
757
+ False
758
+ """
759
+ for player in self.player_list:
760
+ results = []
761
+ for coalit in self.ch_f:
762
+ if player in coalit:
763
+ t = tuple(sorted(set(coalit) - {player}))
764
+ results.append(self.ch_f[coalit] == self.ch_f[t])
765
+ if all(results) and payoff_vector[player] != 0:
766
+ return False
767
+ return True
768
+
769
+ def is_symmetric(self, payoff_vector):
770
+ r"""
771
+ Return ``True`` if ``payoff_vector`` possesses the symmetry property.
772
+
773
+ A payoff vector possesses the symmetry property if
774
+ `v(C \cup i) = v(C \cup j)` for all
775
+ `C \in 2^{\Omega} \setminus \{i,j\}`, then `x_i = x_j`.
776
+
777
+ INPUT:
778
+
779
+ - ``payoff_vector`` -- dictionary where the key is the player
780
+ and the value is their payoff
781
+
782
+ EXAMPLES:
783
+
784
+ A payoff vector that has the symmetry property::
785
+
786
+ sage: letter_function = {(): 0,
787
+ ....: ('A',): 6,
788
+ ....: ('B',): 12,
789
+ ....: ('C',): 42,
790
+ ....: ('A', 'B',): 12,
791
+ ....: ('A', 'C',): 42,
792
+ ....: ('B', 'C',): 42,
793
+ ....: ('A', 'B', 'C',): 42}
794
+ sage: letter_game = CooperativeGame(letter_function)
795
+ sage: letter_game.is_symmetric({'A': 5, 'B': 14, 'C': 20})
796
+ True
797
+
798
+ A payoff vector that returns ``False``::
799
+
800
+ sage: integer_function = {(): 0,
801
+ ....: (1,): 12,
802
+ ....: (2,): 12,
803
+ ....: (3,): 42,
804
+ ....: (1, 2,): 12,
805
+ ....: (1, 3,): 42,
806
+ ....: (2, 3,): 42,
807
+ ....: (1, 2, 3,): 42}
808
+ sage: integer_game = CooperativeGame(integer_function)
809
+ sage: integer_game.is_symmetric({1: 2, 2: 5, 3: 35})
810
+ False
811
+
812
+ A longer example for symmetry::
813
+
814
+ sage: long_function = {(): 0,
815
+ ....: (1,): 0,
816
+ ....: (2,): 0,
817
+ ....: (3,): 0,
818
+ ....: (4,): 0,
819
+ ....: (1, 2): 0,
820
+ ....: (1, 3): 0,
821
+ ....: (1, 4): 0,
822
+ ....: (2, 3): 0,
823
+ ....: (2, 4): 0,
824
+ ....: (3, 4): 0,
825
+ ....: (1, 2, 3): 0,
826
+ ....: (1, 2, 4): 45,
827
+ ....: (1, 3, 4): 40,
828
+ ....: (2, 3, 4): 0,
829
+ ....: (1, 2, 3, 4): 65}
830
+ sage: long_game = CooperativeGame(long_function)
831
+ sage: long_game.is_symmetric({1: 20, 2: 20, 3: 5, 4: 20})
832
+ True
833
+ """
834
+ sets = self.ch_f.keys()
835
+ element = [i for i in sets if len(i) == 1]
836
+ for c1, c2 in combinations(element, 2):
837
+ results = []
838
+ for m in sets:
839
+ junion = tuple(sorted(set(c1) | set(m)))
840
+ kunion = tuple(sorted(set(c2) | set(m)))
841
+ results.append(self.ch_f[junion] == self.ch_f[kunion])
842
+ if all(results) and payoff_vector[c1[0]] != payoff_vector[c2[0]]:
843
+ return False
844
+ return True