passagemath-graphs 10.6.1rc1__cp310-cp310-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
  2. passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
  3. passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
  4. passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
  5. passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
  6. passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
  7. passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
  8. sage/all__sagemath_graphs.py +39 -0
  9. sage/combinat/abstract_tree.py +2723 -0
  10. sage/combinat/all__sagemath_graphs.py +34 -0
  11. sage/combinat/binary_tree.py +5306 -0
  12. sage/combinat/cluster_algebra_quiver/all.py +22 -0
  13. sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
  14. sage/combinat/cluster_algebra_quiver/interact.py +124 -0
  15. sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
  16. sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
  17. sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
  18. sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
  19. sage/combinat/designs/MOLS_handbook_data.py +570 -0
  20. sage/combinat/designs/all.py +58 -0
  21. sage/combinat/designs/bibd.py +1655 -0
  22. sage/combinat/designs/block_design.py +1071 -0
  23. sage/combinat/designs/covering_array.py +269 -0
  24. sage/combinat/designs/covering_design.py +530 -0
  25. sage/combinat/designs/database.py +5615 -0
  26. sage/combinat/designs/design_catalog.py +122 -0
  27. sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  28. sage/combinat/designs/designs_pyx.pxd +21 -0
  29. sage/combinat/designs/designs_pyx.pyx +993 -0
  30. sage/combinat/designs/difference_family.py +3951 -0
  31. sage/combinat/designs/difference_matrices.py +279 -0
  32. sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  33. sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
  34. sage/combinat/designs/ext_rep.py +1064 -0
  35. sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
  36. sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
  37. sage/combinat/designs/group_divisible_designs.py +361 -0
  38. sage/combinat/designs/incidence_structures.py +2357 -0
  39. sage/combinat/designs/latin_squares.py +581 -0
  40. sage/combinat/designs/orthogonal_arrays.py +2244 -0
  41. sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
  42. sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
  43. sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
  44. sage/combinat/designs/resolvable_bibd.py +815 -0
  45. sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
  46. sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
  47. sage/combinat/designs/subhypergraph_search.pyx +530 -0
  48. sage/combinat/designs/twographs.py +306 -0
  49. sage/combinat/finite_state_machine.py +14874 -0
  50. sage/combinat/finite_state_machine_generators.py +2006 -0
  51. sage/combinat/graph_path.py +448 -0
  52. sage/combinat/interval_posets.py +3908 -0
  53. sage/combinat/nu_tamari_lattice.py +269 -0
  54. sage/combinat/ordered_tree.py +1446 -0
  55. sage/combinat/posets/all.py +46 -0
  56. sage/combinat/posets/bubble_shuffle.py +247 -0
  57. sage/combinat/posets/cartesian_product.py +493 -0
  58. sage/combinat/posets/d_complete.py +182 -0
  59. sage/combinat/posets/elements.py +273 -0
  60. sage/combinat/posets/forest.py +30 -0
  61. sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
  62. sage/combinat/posets/hasse_cython.pyx +174 -0
  63. sage/combinat/posets/hasse_diagram.py +3672 -0
  64. sage/combinat/posets/hochschild_lattice.py +158 -0
  65. sage/combinat/posets/incidence_algebras.py +794 -0
  66. sage/combinat/posets/lattices.py +5117 -0
  67. sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
  68. sage/combinat/posets/linear_extension_iterator.pyx +292 -0
  69. sage/combinat/posets/linear_extensions.py +1037 -0
  70. sage/combinat/posets/mobile.py +275 -0
  71. sage/combinat/posets/moebius_algebra.py +776 -0
  72. sage/combinat/posets/poset_examples.py +2178 -0
  73. sage/combinat/posets/posets.py +9360 -0
  74. sage/combinat/rooted_tree.py +1070 -0
  75. sage/combinat/shard_order.py +239 -0
  76. sage/combinat/tamari_lattices.py +384 -0
  77. sage/combinat/yang_baxter_graph.py +923 -0
  78. sage/databases/all__sagemath_graphs.py +1 -0
  79. sage/databases/knotinfo_db.py +1231 -0
  80. sage/ext_data/all__sagemath_graphs.py +1 -0
  81. sage/ext_data/graphs/graph_plot_js.html +330 -0
  82. sage/ext_data/kenzo/CP2.txt +45 -0
  83. sage/ext_data/kenzo/CP3.txt +349 -0
  84. sage/ext_data/kenzo/CP4.txt +4774 -0
  85. sage/ext_data/kenzo/README.txt +49 -0
  86. sage/ext_data/kenzo/S4.txt +20 -0
  87. sage/graphs/all.py +42 -0
  88. sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
  89. sage/graphs/asteroidal_triples.pyx +320 -0
  90. sage/graphs/base/all.py +1 -0
  91. sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  92. sage/graphs/base/boost_graph.pxd +106 -0
  93. sage/graphs/base/boost_graph.pyx +3045 -0
  94. sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  95. sage/graphs/base/c_graph.pxd +106 -0
  96. sage/graphs/base/c_graph.pyx +5096 -0
  97. sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  98. sage/graphs/base/dense_graph.pxd +28 -0
  99. sage/graphs/base/dense_graph.pyx +801 -0
  100. sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
  101. sage/graphs/base/graph_backends.pxd +5 -0
  102. sage/graphs/base/graph_backends.pyx +797 -0
  103. sage/graphs/base/overview.py +85 -0
  104. sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  105. sage/graphs/base/sparse_graph.pxd +90 -0
  106. sage/graphs/base/sparse_graph.pyx +1653 -0
  107. sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  108. sage/graphs/base/static_dense_graph.pxd +5 -0
  109. sage/graphs/base/static_dense_graph.pyx +1032 -0
  110. sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
  111. sage/graphs/base/static_sparse_backend.pxd +27 -0
  112. sage/graphs/base/static_sparse_backend.pyx +1583 -0
  113. sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  114. sage/graphs/base/static_sparse_graph.pxd +37 -0
  115. sage/graphs/base/static_sparse_graph.pyx +1375 -0
  116. sage/graphs/bipartite_graph.py +2732 -0
  117. sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
  118. sage/graphs/centrality.pyx +1038 -0
  119. sage/graphs/cographs.py +519 -0
  120. sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
  121. sage/graphs/comparability.pyx +851 -0
  122. sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  123. sage/graphs/connectivity.pxd +157 -0
  124. sage/graphs/connectivity.pyx +4813 -0
  125. sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
  126. sage/graphs/convexity_properties.pxd +16 -0
  127. sage/graphs/convexity_properties.pyx +870 -0
  128. sage/graphs/digraph.py +4754 -0
  129. sage/graphs/digraph_generators.py +1993 -0
  130. sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
  131. sage/graphs/distances_all_pairs.pxd +12 -0
  132. sage/graphs/distances_all_pairs.pyx +2938 -0
  133. sage/graphs/domination.py +1363 -0
  134. sage/graphs/dot2tex_utils.py +100 -0
  135. sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  136. sage/graphs/edge_connectivity.pyx +1215 -0
  137. sage/graphs/generators/all.py +1 -0
  138. sage/graphs/generators/basic.py +1769 -0
  139. sage/graphs/generators/chessboard.py +538 -0
  140. sage/graphs/generators/classical_geometries.py +1611 -0
  141. sage/graphs/generators/degree_sequence.py +235 -0
  142. sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
  143. sage/graphs/generators/distance_regular.pyx +2846 -0
  144. sage/graphs/generators/families.py +4759 -0
  145. sage/graphs/generators/intersection.py +565 -0
  146. sage/graphs/generators/platonic_solids.py +262 -0
  147. sage/graphs/generators/random.py +2623 -0
  148. sage/graphs/generators/smallgraphs.py +5741 -0
  149. sage/graphs/generators/world_map.py +724 -0
  150. sage/graphs/generic_graph.py +26867 -0
  151. sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  152. sage/graphs/generic_graph_pyx.pxd +34 -0
  153. sage/graphs/generic_graph_pyx.pyx +1673 -0
  154. sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
  155. sage/graphs/genus.pyx +622 -0
  156. sage/graphs/graph.py +9645 -0
  157. sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
  158. sage/graphs/graph_coloring.pyx +2284 -0
  159. sage/graphs/graph_database.py +1177 -0
  160. sage/graphs/graph_decompositions/all.py +1 -0
  161. sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  162. sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
  163. sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
  164. sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
  165. sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  166. sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
  167. sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
  168. sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
  169. sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
  170. sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
  171. sage/graphs/graph_decompositions/graph_products.pyx +508 -0
  172. sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  173. sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
  174. sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
  175. sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  176. sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
  177. sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
  178. sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  179. sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
  180. sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
  181. sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
  182. sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
  183. sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
  184. sage/graphs/graph_editor.py +82 -0
  185. sage/graphs/graph_generators.py +3314 -0
  186. sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  187. sage/graphs/graph_generators_pyx.pyx +95 -0
  188. sage/graphs/graph_input.py +812 -0
  189. sage/graphs/graph_latex.py +2064 -0
  190. sage/graphs/graph_list.py +410 -0
  191. sage/graphs/graph_plot.py +1756 -0
  192. sage/graphs/graph_plot_js.py +338 -0
  193. sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
  194. sage/graphs/hyperbolicity.pyx +1704 -0
  195. sage/graphs/hypergraph_generators.py +364 -0
  196. sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  197. sage/graphs/independent_sets.pxd +13 -0
  198. sage/graphs/independent_sets.pyx +402 -0
  199. sage/graphs/isgci.py +1033 -0
  200. sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
  201. sage/graphs/isoperimetric_inequalities.pyx +489 -0
  202. sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  203. sage/graphs/line_graph.pyx +743 -0
  204. sage/graphs/lovasz_theta.py +77 -0
  205. sage/graphs/matching.py +1633 -0
  206. sage/graphs/matching_covered_graph.py +3590 -0
  207. sage/graphs/orientations.py +1489 -0
  208. sage/graphs/partial_cube.py +459 -0
  209. sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
  210. sage/graphs/path_enumeration.pyx +2040 -0
  211. sage/graphs/pq_trees.py +1129 -0
  212. sage/graphs/print_graphs.py +201 -0
  213. sage/graphs/schnyder.py +865 -0
  214. sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
  215. sage/graphs/spanning_tree.pyx +1457 -0
  216. sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
  217. sage/graphs/strongly_regular_db.pyx +3340 -0
  218. sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
  219. sage/graphs/traversals.pxd +9 -0
  220. sage/graphs/traversals.pyx +1872 -0
  221. sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
  222. sage/graphs/trees.pxd +15 -0
  223. sage/graphs/trees.pyx +310 -0
  224. sage/graphs/tutte_polynomial.py +713 -0
  225. sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
  226. sage/graphs/views.pyx +794 -0
  227. sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
  228. sage/graphs/weakly_chordal.pyx +604 -0
  229. sage/groups/all__sagemath_graphs.py +1 -0
  230. sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
  231. sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
  232. sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
  233. sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
  234. sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
  235. sage/knots/all.py +6 -0
  236. sage/knots/free_knotinfo_monoid.py +507 -0
  237. sage/knots/gauss_code.py +291 -0
  238. sage/knots/knot.py +682 -0
  239. sage/knots/knot_table.py +284 -0
  240. sage/knots/knotinfo.py +2900 -0
  241. sage/knots/link.py +4715 -0
  242. sage/sandpiles/all.py +13 -0
  243. sage/sandpiles/examples.py +225 -0
  244. sage/sandpiles/sandpile.py +6365 -0
  245. sage/topology/all.py +22 -0
  246. sage/topology/cell_complex.py +1214 -0
  247. sage/topology/cubical_complex.py +1976 -0
  248. sage/topology/delta_complex.py +1806 -0
  249. sage/topology/filtered_simplicial_complex.py +744 -0
  250. sage/topology/moment_angle_complex.py +823 -0
  251. sage/topology/simplicial_complex.py +5160 -0
  252. sage/topology/simplicial_complex_catalog.py +92 -0
  253. sage/topology/simplicial_complex_examples.py +1680 -0
  254. sage/topology/simplicial_complex_homset.py +205 -0
  255. sage/topology/simplicial_complex_morphism.py +836 -0
  256. sage/topology/simplicial_set.py +4102 -0
  257. sage/topology/simplicial_set_catalog.py +55 -0
  258. sage/topology/simplicial_set_constructions.py +2954 -0
  259. sage/topology/simplicial_set_examples.py +865 -0
  260. sage/topology/simplicial_set_morphism.py +1464 -0
@@ -0,0 +1,565 @@
1
+ # sage_setup: distribution = sagemath-graphs
2
+ r"""
3
+ Intersection graphs
4
+
5
+ The methods defined here appear in :mod:`sage.graphs.graph_generators`.
6
+ """
7
+
8
+ # ****************************************************************************
9
+ # Copyright (C) 2006 Robert L. Miller <rlmillster@gmail.com>
10
+ # Copyright (C) 2006 Emily A. Kirkman
11
+ # Copyright (C) 2009 Michael C. Yurko <myurko@gmail.com>
12
+ #
13
+ # This program is free software: you can redistribute it and/or modify
14
+ # it under the terms of the GNU General Public License as published by
15
+ # the Free Software Foundation, either version 2 of the License, or
16
+ # (at your option) any later version.
17
+ # https://www.gnu.org/licenses/
18
+ # ****************************************************************************
19
+
20
+ # import from Sage library
21
+ from sage.graphs.graph import Graph
22
+
23
+
24
+ def IntervalGraph(intervals, points_ordered=False):
25
+ r"""
26
+ Return the graph corresponding to the given intervals.
27
+
28
+ An interval graph is built from a list `(a_i,b_i)_{1\leq i \leq n}` of
29
+ intervals : to each interval of the list is associated one vertex, two
30
+ vertices being adjacent if the two corresponding (closed) intervals
31
+ intersect.
32
+
33
+ INPUT:
34
+
35
+ - ``intervals`` -- the list of pairs `(a_i,b_i)` defining the graph
36
+
37
+ - ``points_ordered`` -- states whether every interval `(a_i,b_i)` of
38
+ `intervals` satisfies `a_i<b_i`. If satisfied then setting
39
+ ``points_ordered`` to ``True`` will speed up the creation of the graph.
40
+
41
+ .. NOTE::
42
+
43
+ * The vertices are named 0, 1, 2, and so on. The intervals used
44
+ to create the graph are saved with the graph and can be recovered
45
+ using ``get_vertex()`` or ``get_vertices()``.
46
+
47
+ EXAMPLES:
48
+
49
+ The following line creates the sequence of intervals
50
+ `(i, i+2)` for i in `[0, ..., 8]`::
51
+
52
+ sage: intervals = [(i,i+2) for i in range(9)]
53
+
54
+ In the corresponding graph ::
55
+
56
+ sage: g = graphs.IntervalGraph(intervals)
57
+ sage: g.get_vertex(3)
58
+ (3, 5)
59
+ sage: neigh = g.neighbors(3)
60
+ sage: for v in neigh: print(g.get_vertex(v))
61
+ (1, 3)
62
+ (2, 4)
63
+ (4, 6)
64
+ (5, 7)
65
+
66
+ The is_interval() method verifies that this graph is an interval graph. ::
67
+
68
+ sage: g.is_interval()
69
+ True
70
+
71
+ The intervals in the list need not be distinct. ::
72
+
73
+ sage: intervals = [ (1,2), (1,2), (1,2), (2,3), (3,4) ]
74
+ sage: g = graphs.IntervalGraph(intervals,True)
75
+ sage: g.clique_maximum() # needs cliquer
76
+ [0, 1, 2, 3]
77
+ sage: g.get_vertices()
78
+ {0: (1, 2), 1: (1, 2), 2: (1, 2), 3: (2, 3), 4: (3, 4)}
79
+
80
+ The endpoints of the intervals are not ordered we get the same graph
81
+ (except for the vertex labels). ::
82
+
83
+ sage: rev_intervals = [ (2,1), (2,1), (2,1), (3,2), (4,3) ]
84
+ sage: h = graphs.IntervalGraph(rev_intervals,False)
85
+ sage: h.get_vertices()
86
+ {0: (2, 1), 1: (2, 1), 2: (2, 1), 3: (3, 2), 4: (4, 3)}
87
+ sage: g.edges(sort=True) == h.edges(sort=True)
88
+ True
89
+ """
90
+ intervals = list(intervals)
91
+ n = len(intervals)
92
+ g = Graph(n)
93
+
94
+ if points_ordered:
95
+ for i in range(n - 1):
96
+ li, ri = intervals[i]
97
+ for j in range(i + 1, n):
98
+ lj, rj = intervals[j]
99
+ if ri < lj or rj < li:
100
+ continue
101
+ g.add_edge(i, j)
102
+ else:
103
+ for i in range(n - 1):
104
+ min_I = min(intervals[i])
105
+ max_I = max(intervals[i])
106
+ for j in range(i + 1, n):
107
+ J = intervals[j]
108
+ if max_I < min(J) or max(J) < min_I:
109
+ continue
110
+ g.add_edge(i, j)
111
+
112
+ rep = dict(zip(range(n), intervals))
113
+ g.set_vertices(rep)
114
+
115
+ return g
116
+
117
+
118
+ def PermutationGraph(second_permutation, first_permutation=None):
119
+ r"""
120
+ Build a permutation graph from one permutation or from two lists.
121
+
122
+ Definition:
123
+
124
+ If `\sigma` is a permutation of `\{ 1, 2, \ldots, n \}`, then the
125
+ permutation graph of `\sigma` is the graph on vertex set
126
+ `\{ 1, 2, \ldots, n \}` in which two vertices `i` and `j` satisfying
127
+ `i < j` are connected by an edge if and only if
128
+ `\sigma^{-1}(i) > \sigma^{-1}(j)`. A visual way to construct this
129
+ graph is as follows:
130
+
131
+ Take two horizontal lines in the euclidean plane, and mark points
132
+ `1, ..., n` from left to right on the first of them. On the second
133
+ one, still from left to right, mark `n` points
134
+ `\sigma(1), \sigma(2), \ldots, \sigma(n)`.
135
+ Now, link by a segment the two points marked with `1`, then link
136
+ together the points marked with `2`, and so on. The permutation
137
+ graph of `\sigma` is the intersection graph of those segments: there
138
+ exists a vertex in this graph for each element from `1` to `n`, two
139
+ vertices `i, j` being adjacent if the segments `i` and `j` cross
140
+ each other.
141
+
142
+ The set of edges of the permutation graph can thus be identified with
143
+ the set of inversions of the inverse of the given permutation
144
+ `\sigma`.
145
+
146
+ A more general notion of permutation graph can be defined as
147
+ follows: If `S` is a set, and `(a_1, a_2, \ldots, a_n)` and
148
+ `(b_1, b_2, \ldots, b_n)` are two lists of elements of `S`, each of
149
+ which lists contains every element of `S` exactly once, then the
150
+ permutation graph defined by these two lists is the graph on the
151
+ vertex set `S` in which two vertices `i` and `j` are connected by an
152
+ edge if and only if the order in which these vertices appear in the
153
+ list `(a_1, a_2, \ldots, a_n)` is the opposite of the order in which
154
+ they appear in the list `(b_1, b_2, \ldots, b_n)`. When
155
+ `(a_1, a_2, \ldots, a_n) = (1, 2, \ldots, n)`, this graph is the
156
+ permutation graph of the permutation
157
+ `(b_1, b_2, \ldots, b_n) \in S_n`. Notice that `S` does not have to
158
+ be a set of integers here, but can be a set of strings, tuples, or
159
+ anything else. We can still use the above visual description to
160
+ construct the permutation graph, but now we have to mark points
161
+ `a_1, a_2, \ldots, a_n` from left to right on the first horizontal
162
+ line and points `b_1, b_2, \ldots, b_n` from left to right on the
163
+ second horizontal line.
164
+
165
+ INPUT:
166
+
167
+ - ``second_permutation`` -- the unique permutation/list defining the graph,
168
+ or the second of the two (if the graph is to be built from two
169
+ permutations/lists)
170
+
171
+ - ``first_permutation`` -- (optional) the first of the two
172
+ permutations/lists from which the graph should be built, if it is to be
173
+ built from two permutations/lists
174
+
175
+ When ``first_permutation is None`` (default), it is set to be equal to
176
+ ``sorted(second_permutation)``, which yields the expected ordering when
177
+ the elements of the graph are integers.
178
+
179
+ .. SEEALSO::
180
+
181
+ - Recognition of Permutation graphs in the :mod:`comparability module
182
+ <sage.graphs.comparability>`.
183
+
184
+ - Drawings of permutation graphs as intersection graphs of segments is
185
+ possible through the
186
+ :meth:`~sage.combinat.permutation.Permutation.show` method of
187
+ :class:`~sage.combinat.permutation.Permutation` objects.
188
+
189
+ The correct argument to use in this case is ``show(representation =
190
+ "braid")``.
191
+
192
+ - :meth:`~sage.combinat.permutation.Permutation.inversions`
193
+
194
+ EXAMPLES::
195
+
196
+ sage: p = Permutations(5).random_element()
197
+ sage: PG = graphs.PermutationGraph(p)
198
+ sage: edges = PG.edges(sort=True, labels=False)
199
+ sage: set(edges) == set(p.inverse().inversions())
200
+ True
201
+
202
+ sage: PG = graphs.PermutationGraph([3,4,5,1,2])
203
+ sage: sorted(PG.edges(sort=True))
204
+ [(1, 3, None),
205
+ (1, 4, None),
206
+ (1, 5, None),
207
+ (2, 3, None),
208
+ (2, 4, None),
209
+ (2, 5, None)]
210
+ sage: PG = graphs.PermutationGraph([3,4,5,1,2], [1,4,2,5,3])
211
+ sage: sorted(PG.edges(sort=True))
212
+ [(1, 3, None),
213
+ (1, 4, None),
214
+ (1, 5, None),
215
+ (2, 3, None),
216
+ (2, 5, None),
217
+ (3, 4, None),
218
+ (3, 5, None)]
219
+ sage: PG = graphs.PermutationGraph([1,4,2,5,3], [3,4,5,1,2])
220
+ sage: sorted(PG.edges(sort=True))
221
+ [(1, 3, None),
222
+ (1, 4, None),
223
+ (1, 5, None),
224
+ (2, 3, None),
225
+ (2, 5, None),
226
+ (3, 4, None),
227
+ (3, 5, None)]
228
+
229
+ sage: PG = graphs.PermutationGraph(Permutation([1,3,2]), Permutation([1,2,3]))
230
+ sage: sorted(PG.edges(sort=True))
231
+ [(2, 3, None)]
232
+
233
+ sage: graphs.PermutationGraph([]).edges(sort=True)
234
+ []
235
+ sage: graphs.PermutationGraph([], []).edges(sort=True)
236
+ []
237
+
238
+ sage: PG = graphs.PermutationGraph("graph", "phrag")
239
+ sage: sorted(PG.edges(sort=True))
240
+ [('a', 'g', None),
241
+ ('a', 'h', None),
242
+ ('a', 'p', None),
243
+ ('g', 'h', None),
244
+ ('g', 'p', None),
245
+ ('g', 'r', None),
246
+ ('h', 'r', None),
247
+ ('p', 'r', None)]
248
+
249
+ TESTS::
250
+
251
+ sage: graphs.PermutationGraph([1, 2, 3], [4, 5, 6])
252
+ Traceback (most recent call last):
253
+ ...
254
+ ValueError: The two permutations do not contain the same set of elements ...
255
+ """
256
+ if first_permutation is None:
257
+ first_permutation = sorted(second_permutation)
258
+ else:
259
+ if set(second_permutation) != set(first_permutation):
260
+ raise ValueError("The two permutations do not contain the same "
261
+ "set of elements ! It is going to be pretty "
262
+ "hard to define a permutation graph from that !")
263
+
264
+ vertex_to_index = {}
265
+ for i, v in enumerate(first_permutation):
266
+ vertex_to_index[v] = i + 1
267
+
268
+ from sage.combinat.permutation import Permutation
269
+ p2 = Permutation([vertex_to_index[x] for x in second_permutation])
270
+ p2 = p2.inverse()
271
+
272
+ g = Graph(name="Permutation graph for "+str(second_permutation))
273
+ g.add_vertices(second_permutation)
274
+
275
+ for u, v in p2.inversions():
276
+ g.add_edge(first_permutation[u - 1], first_permutation[v - 1])
277
+
278
+ return g
279
+
280
+
281
+ def ToleranceGraph(tolrep):
282
+ r"""
283
+ Return the graph generated by the tolerance representation ``tolrep``.
284
+
285
+ The tolerance representation ``tolrep`` is described by the list
286
+ `((l_0,r_0,t_0), (l_1,r_1,t_1), \ldots, (l_k,r_k,t_k))` where `I_i =
287
+ (l_i,r_i)` denotes a closed interval on the real line with `l_i < r_i` and
288
+ `t_i` a strictly positive value, called tolerance. This representation
289
+ generates the tolerance graph with the vertex set `\{0,1, \ldots, k\}` and
290
+ the edge set `\{(i,j): |I_i \cap I_j| \ge \min\{t_i, t_j\}\}` where `|I_i
291
+ \cap I_j|` denotes the length of the intersection of `I_i` and `I_j`.
292
+
293
+ INPUT:
294
+
295
+ - ``tolrep`` -- list of triples `(l_i,r_i,t_i)` where `(l_i,r_i)` denotes a
296
+ closed interval on the real line and `t_i` a positive value
297
+
298
+ .. NOTE::
299
+
300
+ The vertices are named `0, 1, \ldots, k`. The tolerance representation
301
+ used to create the graph is saved with the graph and can be recovered
302
+ using ``get_vertex()`` or ``get_vertices()``.
303
+
304
+ EXAMPLES:
305
+
306
+ The following code creates a tolerance representation ``tolrep``, generates
307
+ its tolerance graph ``g``, and applies some checks::
308
+
309
+ sage: tolrep = [(1,4,3),(1,2,1),(2,3,1),(0,3,3)]
310
+ sage: g = graphs.ToleranceGraph(tolrep)
311
+ sage: g.get_vertex(3)
312
+ (0, 3, 3)
313
+ sage: neigh = g.neighbors(3)
314
+ sage: for v in neigh: print(g.get_vertex(v))
315
+ (1, 2, 1)
316
+ (2, 3, 1)
317
+ sage: g.is_interval()
318
+ False
319
+ sage: g.is_weakly_chordal()
320
+ True
321
+
322
+ The intervals in the list need not be distinct ::
323
+
324
+ sage: tolrep2 = [(0,4,5),(1,2,1),(2,3,1),(0,4,5)]
325
+ sage: g2 = graphs.ToleranceGraph(tolrep2)
326
+ sage: g2.get_vertices()
327
+ {0: (0, 4, 5), 1: (1, 2, 1), 2: (2, 3, 1), 3: (0, 4, 5)}
328
+ sage: g2.is_isomorphic(g)
329
+ True
330
+
331
+ Real values are also allowed ::
332
+
333
+ sage: tolrep = [(0.1,3.3,4.4),(1.1,2.5,1.1),(1.4,4.4,3.3)]
334
+ sage: g = graphs.ToleranceGraph(tolrep)
335
+ sage: g.is_isomorphic(graphs.PathGraph(3))
336
+ True
337
+
338
+ TESTS:
339
+
340
+ Giving negative third value::
341
+
342
+ sage: tolrep = [(0.1,3.3,-4.4),(1.1,2.5,1.1),(1.4,4.4,3.3)]
343
+ sage: g = graphs.ToleranceGraph(tolrep)
344
+ Traceback (most recent call last):
345
+ ...
346
+ ValueError: Invalid tolerance representation at position 0; third value must be > 0
347
+ sage: g = graphs.ToleranceGraph([(1, 2, 0)])
348
+ Traceback (most recent call last):
349
+ ...
350
+ ValueError: Invalid tolerance representation at position 0; third value must be > 0
351
+ """
352
+ n = len(tolrep)
353
+
354
+ for i in range(n):
355
+ if tolrep[i][2] <= 0:
356
+ raise ValueError("Invalid tolerance representation at position "
357
+ "{}; third value must be > 0".format(i))
358
+
359
+ g = Graph(n, name="Tolerance Graph")
360
+
361
+ for i in range(n):
362
+ li, ri, ti = tolrep[i]
363
+ for j in range(i + 1, n):
364
+ lj, rj, tj = tolrep[j]
365
+ if min(ri, rj) - max(li, lj) >= min(ti, tj):
366
+ g.add_edge(i, j)
367
+
368
+ rep = dict(zip(range(n), tolrep))
369
+ g.set_vertices(rep)
370
+
371
+ return g
372
+
373
+
374
+ def OrthogonalArrayBlockGraph(k, n, OA=None):
375
+ r"""
376
+ Return the graph of an `OA(k,n)`.
377
+
378
+ The intersection graph of the blocks of a transversal design with parameters
379
+ `(k,n)`, or `TD(k,n)` for short, is a strongly regular graph (unless it is a
380
+ complete graph). Its parameters `(v,k',\lambda,\mu)` are determined by the
381
+ parameters `k,n` via:
382
+
383
+ .. MATH::
384
+
385
+ v=n^2, k'=k(n-1), \lambda=(k-1)(k-2)+n-2, \mu=k(k-1)
386
+
387
+ As transversal designs and orthogonal arrays (OA for short) are equivalent
388
+ objects, this graph can also be built from the blocks of an `OA(k,n)`, two
389
+ of them being adjacent if one of their coordinates match.
390
+
391
+ For more information on these graphs, see `Andries Brouwer's page
392
+ on Orthogonal Array graphs <https://www.win.tue.nl/~aeb/graphs/OA.html>`_.
393
+
394
+ .. WARNING::
395
+
396
+ - Brouwer's website uses the notation `OA(n,k)` instead of `OA(k,n)`
397
+
398
+ - For given parameters `k` and `n` there can be many `OA(k,n)` : the
399
+ graphs returned are not uniquely defined by their parameters (see the
400
+ examples below).
401
+
402
+ - If the function is called only with the parameter ``k`` and ``n`` the
403
+ results might be different with two versions of Sage, or even worse :
404
+ some could not be available anymore.
405
+
406
+ .. SEEALSO::
407
+
408
+ :mod:`sage.combinat.designs.orthogonal_arrays`
409
+
410
+ INPUT:
411
+
412
+ - ``k``, ``n`` -- integers
413
+
414
+ - ``OA`` -- an orthogonal array; if set to ``None`` (default) then
415
+ :func:`~sage.combinat.designs.orthogonal_arrays.orthogonal_array` is
416
+ called to compute an `OA(k,n)`
417
+
418
+ EXAMPLES::
419
+
420
+ sage: # needs sage.modules
421
+ sage: G = graphs.OrthogonalArrayBlockGraph(5,5); G # needs sage.schemes
422
+ OA(5,5): Graph on 25 vertices
423
+ sage: G.is_strongly_regular(parameters=True) # needs sage.schemes
424
+ (25, 20, 15, 20)
425
+ sage: G = graphs.OrthogonalArrayBlockGraph(4,10); G
426
+ OA(4,10): Graph on 100 vertices
427
+ sage: G.is_strongly_regular(parameters=True)
428
+ (100, 36, 14, 12)
429
+
430
+ Two graphs built from different orthogonal arrays are also different::
431
+
432
+ sage: # needs sage.modules
433
+ sage: k = 4; n = 10
434
+ sage: OAa = designs.orthogonal_arrays.build(k,n)
435
+ sage: OAb = [[(x+1)%n for x in R] for R in OAa]
436
+ sage: set(map(tuple,OAa)) == set(map(tuple,OAb))
437
+ False
438
+ sage: Ga = graphs.OrthogonalArrayBlockGraph(k, n, OAa)
439
+ sage: Gb = graphs.OrthogonalArrayBlockGraph(k, n, OAb)
440
+ sage: Ga == Gb
441
+ False
442
+
443
+ As ``OAb`` was obtained from ``OAa`` by a relabelling the two graphs are
444
+ isomorphic::
445
+
446
+ sage: Ga.is_isomorphic(Gb) # needs sage.modules
447
+ True
448
+
449
+ But there are examples of `OA(k,n)` for which the resulting graphs are not
450
+ isomorphic::
451
+
452
+ sage: oa0 = [[0, 0, 1], [0, 1, 3], [0, 2, 0], [0, 3, 2],
453
+ ....: [1, 0, 3], [1, 1, 1], [1, 2, 2], [1, 3, 0],
454
+ ....: [2, 0, 0], [2, 1, 2], [2, 2, 1], [2, 3, 3],
455
+ ....: [3, 0, 2], [3, 1, 0], [3, 2, 3], [3, 3, 1]]
456
+ sage: oa1 = [[0, 0, 1], [0, 1, 0], [0, 2, 3], [0, 3, 2],
457
+ ....: [1, 0, 3], [1, 1, 2], [1, 2, 0], [1, 3, 1],
458
+ ....: [2, 0, 0], [2, 1, 1], [2, 2, 2], [2, 3, 3],
459
+ ....: [3, 0, 2], [3, 1, 3], [3, 2, 1], [3, 3, 0]]
460
+ sage: g0 = graphs.OrthogonalArrayBlockGraph(3, 4, oa0) # needs sage.modules
461
+ sage: g1 = graphs.OrthogonalArrayBlockGraph(3, 4, oa1) # needs sage.modules
462
+ sage: g0.is_isomorphic(g1) # needs sage.modules
463
+ False
464
+
465
+ But nevertheless isospectral::
466
+
467
+ sage: g0.spectrum() # needs sage.modules sage.rings.number_field
468
+ [9, 1, 1, 1, 1, 1, 1, 1, 1, 1, -3, -3, -3, -3, -3, -3]
469
+ sage: g1.spectrum() # needs sage.modules sage.rings.number_field
470
+ [9, 1, 1, 1, 1, 1, 1, 1, 1, 1, -3, -3, -3, -3, -3, -3]
471
+
472
+ Note that the graph ``g0`` is actually isomorphic to the affine polar graph
473
+ `VO^+(4,2)`::
474
+
475
+ sage: graphs.AffineOrthogonalPolarGraph(4,2,'+').is_isomorphic(g0) # needs sage.libs.gap sage.modules
476
+ True
477
+
478
+ TESTS::
479
+
480
+ sage: G = graphs.OrthogonalArrayBlockGraph(4,6) # needs sage.modules sage.schemes
481
+ Traceback (most recent call last):
482
+ ...
483
+ NotImplementedError: I don't know how to build an OA(4,6)!
484
+ sage: G = graphs.OrthogonalArrayBlockGraph(8,2) # needs sage.modules
485
+ Traceback (most recent call last):
486
+ ...
487
+ ValueError: There is no OA(8,2). Beware, Brouwer's website uses OA(n,k) instead of OA(k,n) !
488
+ """
489
+ if n > 1 and k >= n + 2:
490
+ raise ValueError("There is no OA({},{}). Beware, Brouwer's website uses OA(n,k) instead of OA(k,n) !".format(k, n))
491
+
492
+ from itertools import combinations
493
+
494
+ if OA is None:
495
+ from sage.combinat.designs.orthogonal_arrays import orthogonal_array
496
+ OA = orthogonal_array(k, n)
497
+ else:
498
+ assert len(OA) == n**2
499
+ assert n == 0 or k == len(OA[0])
500
+
501
+ OA = map(tuple, OA)
502
+
503
+ d = [[[] for j in range(n)] for i in range(k)]
504
+ for R in OA:
505
+ for i, x in enumerate(R):
506
+ d[i][x].append(R)
507
+
508
+ g = Graph()
509
+ for L in d:
510
+ for ll in L:
511
+ g.add_edges(combinations(ll, 2))
512
+
513
+ g.name("OA({},{})".format(k, n))
514
+
515
+ return g
516
+
517
+
518
+ def IntersectionGraph(S):
519
+ r"""
520
+ Return the intersection graph of the family `S`.
521
+
522
+ The intersection graph of a family `S` is a graph `G` with `V(G)=S` such
523
+ that two elements `s_1,s_2\in S` are adjacent in `G` if and only if `s_1\cap
524
+ s_2\neq \emptyset`.
525
+
526
+ INPUT:
527
+
528
+ - ``S`` -- list of sets/tuples/iterables
529
+
530
+ .. NOTE::
531
+
532
+ The elements of `S` must be finite, hashable, and the elements of
533
+ any `s\in S` must be hashable too.
534
+
535
+ EXAMPLES::
536
+
537
+ sage: graphs.IntersectionGraph([(1,2,3),(3,4,5),(5,6,7)])
538
+ Intersection Graph: Graph on 3 vertices
539
+
540
+ TESTS::
541
+
542
+ sage: graphs.IntersectionGraph([(1,2,[1])])
543
+ Traceback (most recent call last):
544
+ ...
545
+ TypeError: The elements of S must be hashable, and this one is not: (1, 2, [1])
546
+ """
547
+ for s in S:
548
+ try:
549
+ hash(s)
550
+ except TypeError:
551
+ raise TypeError("The elements of S must be hashable, and this one is not: {}".format(s))
552
+
553
+ ground_set_to_sets = {}
554
+ for s in S:
555
+ for x in s:
556
+ if x not in ground_set_to_sets:
557
+ ground_set_to_sets[x] = []
558
+ ground_set_to_sets[x].append(s)
559
+
560
+ g = Graph(name="Intersection Graph")
561
+ g.add_vertices(S)
562
+ for clique in ground_set_to_sets.values():
563
+ g.add_clique(set(clique))
564
+
565
+ return g