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.
- passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
- passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
- passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
- passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
- passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
- passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
- passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
- sage/all__sagemath_graphs.py +39 -0
- sage/combinat/abstract_tree.py +2723 -0
- sage/combinat/all__sagemath_graphs.py +34 -0
- sage/combinat/binary_tree.py +5306 -0
- sage/combinat/cluster_algebra_quiver/all.py +22 -0
- sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
- sage/combinat/cluster_algebra_quiver/interact.py +124 -0
- sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
- sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
- sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
- sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
- sage/combinat/designs/MOLS_handbook_data.py +570 -0
- sage/combinat/designs/all.py +58 -0
- sage/combinat/designs/bibd.py +1655 -0
- sage/combinat/designs/block_design.py +1071 -0
- sage/combinat/designs/covering_array.py +269 -0
- sage/combinat/designs/covering_design.py +530 -0
- sage/combinat/designs/database.py +5615 -0
- sage/combinat/designs/design_catalog.py +122 -0
- sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/designs_pyx.pxd +21 -0
- sage/combinat/designs/designs_pyx.pyx +993 -0
- sage/combinat/designs/difference_family.py +3951 -0
- sage/combinat/designs/difference_matrices.py +279 -0
- sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
- sage/combinat/designs/ext_rep.py +1064 -0
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
- sage/combinat/designs/group_divisible_designs.py +361 -0
- sage/combinat/designs/incidence_structures.py +2357 -0
- sage/combinat/designs/latin_squares.py +581 -0
- sage/combinat/designs/orthogonal_arrays.py +2244 -0
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
- sage/combinat/designs/resolvable_bibd.py +815 -0
- sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
- sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +530 -0
- sage/combinat/designs/twographs.py +306 -0
- sage/combinat/finite_state_machine.py +14874 -0
- sage/combinat/finite_state_machine_generators.py +2006 -0
- sage/combinat/graph_path.py +448 -0
- sage/combinat/interval_posets.py +3908 -0
- sage/combinat/nu_tamari_lattice.py +269 -0
- sage/combinat/ordered_tree.py +1446 -0
- sage/combinat/posets/all.py +46 -0
- sage/combinat/posets/bubble_shuffle.py +247 -0
- sage/combinat/posets/cartesian_product.py +493 -0
- sage/combinat/posets/d_complete.py +182 -0
- sage/combinat/posets/elements.py +273 -0
- sage/combinat/posets/forest.py +30 -0
- sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython.pyx +174 -0
- sage/combinat/posets/hasse_diagram.py +3672 -0
- sage/combinat/posets/hochschild_lattice.py +158 -0
- sage/combinat/posets/incidence_algebras.py +794 -0
- sage/combinat/posets/lattices.py +5117 -0
- sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +292 -0
- sage/combinat/posets/linear_extensions.py +1037 -0
- sage/combinat/posets/mobile.py +275 -0
- sage/combinat/posets/moebius_algebra.py +776 -0
- sage/combinat/posets/poset_examples.py +2178 -0
- sage/combinat/posets/posets.py +9360 -0
- sage/combinat/rooted_tree.py +1070 -0
- sage/combinat/shard_order.py +239 -0
- sage/combinat/tamari_lattices.py +384 -0
- sage/combinat/yang_baxter_graph.py +923 -0
- sage/databases/all__sagemath_graphs.py +1 -0
- sage/databases/knotinfo_db.py +1231 -0
- sage/ext_data/all__sagemath_graphs.py +1 -0
- sage/ext_data/graphs/graph_plot_js.html +330 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/graphs/all.py +42 -0
- sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/asteroidal_triples.pyx +320 -0
- sage/graphs/base/all.py +1 -0
- sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/boost_graph.pxd +106 -0
- sage/graphs/base/boost_graph.pyx +3045 -0
- sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/c_graph.pxd +106 -0
- sage/graphs/base/c_graph.pyx +5096 -0
- sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/dense_graph.pxd +28 -0
- sage/graphs/base/dense_graph.pyx +801 -0
- sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/graph_backends.pxd +5 -0
- sage/graphs/base/graph_backends.pyx +797 -0
- sage/graphs/base/overview.py +85 -0
- sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/sparse_graph.pxd +90 -0
- sage/graphs/base/sparse_graph.pyx +1653 -0
- sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_dense_graph.pxd +5 -0
- sage/graphs/base/static_dense_graph.pyx +1032 -0
- sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_backend.pxd +27 -0
- sage/graphs/base/static_sparse_backend.pyx +1583 -0
- sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_graph.pxd +37 -0
- sage/graphs/base/static_sparse_graph.pyx +1375 -0
- sage/graphs/bipartite_graph.py +2732 -0
- sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/centrality.pyx +1038 -0
- sage/graphs/cographs.py +519 -0
- sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/comparability.pyx +851 -0
- sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/connectivity.pxd +157 -0
- sage/graphs/connectivity.pyx +4813 -0
- sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/convexity_properties.pxd +16 -0
- sage/graphs/convexity_properties.pyx +870 -0
- sage/graphs/digraph.py +4754 -0
- sage/graphs/digraph_generators.py +1993 -0
- sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/distances_all_pairs.pxd +12 -0
- sage/graphs/distances_all_pairs.pyx +2938 -0
- sage/graphs/domination.py +1363 -0
- sage/graphs/dot2tex_utils.py +100 -0
- sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/edge_connectivity.pyx +1215 -0
- sage/graphs/generators/all.py +1 -0
- sage/graphs/generators/basic.py +1769 -0
- sage/graphs/generators/chessboard.py +538 -0
- sage/graphs/generators/classical_geometries.py +1611 -0
- sage/graphs/generators/degree_sequence.py +235 -0
- sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generators/distance_regular.pyx +2846 -0
- sage/graphs/generators/families.py +4759 -0
- sage/graphs/generators/intersection.py +565 -0
- sage/graphs/generators/platonic_solids.py +262 -0
- sage/graphs/generators/random.py +2623 -0
- sage/graphs/generators/smallgraphs.py +5741 -0
- sage/graphs/generators/world_map.py +724 -0
- sage/graphs/generic_graph.py +26867 -0
- sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generic_graph_pyx.pxd +34 -0
- sage/graphs/generic_graph_pyx.pyx +1673 -0
- sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/genus.pyx +622 -0
- sage/graphs/graph.py +9645 -0
- sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_coloring.pyx +2284 -0
- sage/graphs/graph_database.py +1177 -0
- sage/graphs/graph_decompositions/all.py +1 -0
- sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
- sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
- sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/graph_products.pyx +508 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
- sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
- sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
- sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
- sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
- sage/graphs/graph_editor.py +82 -0
- sage/graphs/graph_generators.py +3314 -0
- sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_generators_pyx.pyx +95 -0
- sage/graphs/graph_input.py +812 -0
- sage/graphs/graph_latex.py +2064 -0
- sage/graphs/graph_list.py +410 -0
- sage/graphs/graph_plot.py +1756 -0
- sage/graphs/graph_plot_js.py +338 -0
- sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/hyperbolicity.pyx +1704 -0
- sage/graphs/hypergraph_generators.py +364 -0
- sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/independent_sets.pxd +13 -0
- sage/graphs/independent_sets.pyx +402 -0
- sage/graphs/isgci.py +1033 -0
- sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/isoperimetric_inequalities.pyx +489 -0
- sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/line_graph.pyx +743 -0
- sage/graphs/lovasz_theta.py +77 -0
- sage/graphs/matching.py +1633 -0
- sage/graphs/matching_covered_graph.py +3590 -0
- sage/graphs/orientations.py +1489 -0
- sage/graphs/partial_cube.py +459 -0
- sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/path_enumeration.pyx +2040 -0
- sage/graphs/pq_trees.py +1129 -0
- sage/graphs/print_graphs.py +201 -0
- sage/graphs/schnyder.py +865 -0
- sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/spanning_tree.pyx +1457 -0
- sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/strongly_regular_db.pyx +3340 -0
- sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/traversals.pxd +9 -0
- sage/graphs/traversals.pyx +1872 -0
- sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/trees.pxd +15 -0
- sage/graphs/trees.pyx +310 -0
- sage/graphs/tutte_polynomial.py +713 -0
- sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/views.pyx +794 -0
- sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/weakly_chordal.pyx +604 -0
- sage/groups/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
- sage/knots/all.py +6 -0
- sage/knots/free_knotinfo_monoid.py +507 -0
- sage/knots/gauss_code.py +291 -0
- sage/knots/knot.py +682 -0
- sage/knots/knot_table.py +284 -0
- sage/knots/knotinfo.py +2900 -0
- sage/knots/link.py +4715 -0
- sage/sandpiles/all.py +13 -0
- sage/sandpiles/examples.py +225 -0
- sage/sandpiles/sandpile.py +6365 -0
- sage/topology/all.py +22 -0
- sage/topology/cell_complex.py +1214 -0
- sage/topology/cubical_complex.py +1976 -0
- sage/topology/delta_complex.py +1806 -0
- sage/topology/filtered_simplicial_complex.py +744 -0
- sage/topology/moment_angle_complex.py +823 -0
- sage/topology/simplicial_complex.py +5160 -0
- sage/topology/simplicial_complex_catalog.py +92 -0
- sage/topology/simplicial_complex_examples.py +1680 -0
- sage/topology/simplicial_complex_homset.py +205 -0
- sage/topology/simplicial_complex_morphism.py +836 -0
- sage/topology/simplicial_set.py +4102 -0
- sage/topology/simplicial_set_catalog.py +55 -0
- sage/topology/simplicial_set_constructions.py +2954 -0
- sage/topology/simplicial_set_examples.py +865 -0
- sage/topology/simplicial_set_morphism.py +1464 -0
sage/graphs/cographs.py
ADDED
@@ -0,0 +1,519 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
# sage.doctest: needs sage.combinat
|
3
|
+
r"""
|
4
|
+
Cographs
|
5
|
+
|
6
|
+
A cograph is a `P_4`-free graph, that is a graph without induced path of order
|
7
|
+
4. Any cograph may be constructed, starting from the single vertex graph, by a
|
8
|
+
sequence of join and disjoint union operations. See the :wikipedia:`Cograph` for
|
9
|
+
more details on this graph class, and :oeis:`A000084` to know the number of
|
10
|
+
cographs of order `n \geq 1`.
|
11
|
+
|
12
|
+
This module implements the following methods concerning cographs:
|
13
|
+
|
14
|
+
.. csv-table::
|
15
|
+
:class: contentstable
|
16
|
+
:widths: 30, 70
|
17
|
+
:delim: |
|
18
|
+
|
19
|
+
:meth:`cographs` | Return an iterator over the cographs of order `n`.
|
20
|
+
|
21
|
+
Methods
|
22
|
+
-------
|
23
|
+
"""
|
24
|
+
# ****************************************************************************
|
25
|
+
# Copyright (C) 2017-2024 Marianna Spyrakou
|
26
|
+
# 2024 David Coudert <david.coudert@inria.fr>
|
27
|
+
#
|
28
|
+
# This program is free software: you can redistribute it and/or modify
|
29
|
+
# it under the terms of the GNU General Public License as published by
|
30
|
+
# the Free Software Foundation, either version 2 of the License, or
|
31
|
+
# (at your option) any later version.
|
32
|
+
# https://www.gnu.org/licenses/
|
33
|
+
# ****************************************************************************
|
34
|
+
|
35
|
+
from sage.misc.lazy_import import lazy_import
|
36
|
+
|
37
|
+
lazy_import('sage.combinat.partitions', 'AccelAsc_next')
|
38
|
+
|
39
|
+
|
40
|
+
class CoTree:
|
41
|
+
r"""
|
42
|
+
Generic cotree node.
|
43
|
+
|
44
|
+
This data structure is used for the generation of cographs in
|
45
|
+
:meth:`cographs`.
|
46
|
+
"""
|
47
|
+
def __init__(self, name='root'):
|
48
|
+
r"""
|
49
|
+
Initialize a cotree.
|
50
|
+
|
51
|
+
INPUT:
|
52
|
+
|
53
|
+
- ``name`` -- either an operation ('U' or 'J') or the size of the
|
54
|
+
subtree rooted at this node
|
55
|
+
|
56
|
+
EXAMPLES::
|
57
|
+
|
58
|
+
sage: from sage.graphs.cographs import CoTree
|
59
|
+
sage: CoTree(1)
|
60
|
+
( 1 )
|
61
|
+
sage: CoTree()
|
62
|
+
( root )
|
63
|
+
"""
|
64
|
+
self.name = name
|
65
|
+
self.children = []
|
66
|
+
self.info = None
|
67
|
+
self.parent = None
|
68
|
+
|
69
|
+
def __str__(self):
|
70
|
+
r"""
|
71
|
+
Return a string representation of ``self``.
|
72
|
+
|
73
|
+
The subtree of a node is inside brackets and starts with the operation
|
74
|
+
to perform between the children ('J' for join or 'U' for disjoint
|
75
|
+
union).
|
76
|
+
|
77
|
+
EXAMPLES::
|
78
|
+
|
79
|
+
sage: from sage.graphs.cographs import CoTree
|
80
|
+
sage: CoTree(1)
|
81
|
+
( 1 )
|
82
|
+
sage: CoTree('J')
|
83
|
+
[ J ]
|
84
|
+
sage: next(graphs.cographs(4, as_graph=False)) # indirect doctest
|
85
|
+
[ J ( 0 ) ( 1 ) ( 2 ) ( 3 ) ]
|
86
|
+
"""
|
87
|
+
first = '[' if self.name in ['J', 'U'] else '('
|
88
|
+
last = ' ]' if self.name in ['J', 'U'] else ' )'
|
89
|
+
s = f"{first} {self.name}"
|
90
|
+
for child in self.children:
|
91
|
+
s += f' {child}'
|
92
|
+
s += last
|
93
|
+
return s
|
94
|
+
|
95
|
+
__repr__ = __str__
|
96
|
+
|
97
|
+
def add_child(self, node):
|
98
|
+
r"""
|
99
|
+
Add cotree ``node`` in the list of children of ``self``.
|
100
|
+
|
101
|
+
INPUT:
|
102
|
+
|
103
|
+
- ``node`` -- a CoTree
|
104
|
+
|
105
|
+
EXAMPLES::
|
106
|
+
|
107
|
+
sage: from sage.graphs.cographs import CoTree
|
108
|
+
sage: T = CoTree('J')
|
109
|
+
sage: T.add_child(CoTree(1))
|
110
|
+
sage: T
|
111
|
+
[ J ( 1 ) ]
|
112
|
+
"""
|
113
|
+
assert isinstance(node, CoTree)
|
114
|
+
self.children.append(node)
|
115
|
+
node.parent = self
|
116
|
+
|
117
|
+
def copy_tree(self, T):
|
118
|
+
r"""
|
119
|
+
Make `T` a copy of ``self``.
|
120
|
+
|
121
|
+
INPUT:
|
122
|
+
|
123
|
+
- ``T`` -- a CoTree
|
124
|
+
|
125
|
+
EXAMPLES::
|
126
|
+
|
127
|
+
sage: from sage.graphs.cographs import CoTree
|
128
|
+
sage: T = CoTree('J')
|
129
|
+
sage: T.add_child(CoTree(1))
|
130
|
+
sage: T.add_child(CoTree(2))
|
131
|
+
sage: T
|
132
|
+
[ J ( 1 ) ( 2 ) ]
|
133
|
+
sage: B = CoTree('U')
|
134
|
+
sage: T.copy_tree(B)
|
135
|
+
sage: B
|
136
|
+
[ U ( 1 ) ( 2 ) ]
|
137
|
+
"""
|
138
|
+
for i, child in enumerate(self.children):
|
139
|
+
T.add_child(CoTree(child.name))
|
140
|
+
child.copy_tree(T.children[i])
|
141
|
+
|
142
|
+
def reset_info(self):
|
143
|
+
r"""
|
144
|
+
Reset parameter ``info`` from all nodes of ``self``.
|
145
|
+
|
146
|
+
EXAMPLES::
|
147
|
+
|
148
|
+
sage: from sage.graphs.cographs import CoTree
|
149
|
+
sage: T = CoTree(1)
|
150
|
+
sage: B = CoTree(2)
|
151
|
+
sage: T.add_child(B)
|
152
|
+
sage: C = CoTree(3)
|
153
|
+
sage: B.add_child(C)
|
154
|
+
sage: C.info = 'info'
|
155
|
+
sage: T.reset_info()
|
156
|
+
sage: C.info is None
|
157
|
+
True
|
158
|
+
"""
|
159
|
+
for child in self.children:
|
160
|
+
child.reset_info()
|
161
|
+
self.info = None
|
162
|
+
|
163
|
+
|
164
|
+
def rebuild_node(u, P):
|
165
|
+
r"""
|
166
|
+
Replace the subtree rooted at `u` by a subtree induced by partition `P`.
|
167
|
+
|
168
|
+
This is a helper method to method :meth:`cographs`.
|
169
|
+
|
170
|
+
INPUT:
|
171
|
+
|
172
|
+
- ``u`` -- a ``CoTree``
|
173
|
+
|
174
|
+
- ``P`` -- a partition encoding the new structure of the children of `u`
|
175
|
+
|
176
|
+
EXAMPLES::
|
177
|
+
|
178
|
+
sage: next(graphs.cographs(3, as_graph=True)).vertices() # indirect doctest
|
179
|
+
[0, 1, 2]
|
180
|
+
"""
|
181
|
+
if P is None:
|
182
|
+
print('P is None')
|
183
|
+
u.children = [] # delete the subtree rooted at u
|
184
|
+
for value in P:
|
185
|
+
this_child = CoTree(value)
|
186
|
+
u.add_child(this_child)
|
187
|
+
if value > 1:
|
188
|
+
for j in range(value):
|
189
|
+
this_child.add_child(CoTree(1))
|
190
|
+
|
191
|
+
|
192
|
+
def find_pivot(T):
|
193
|
+
r"""
|
194
|
+
Search for a pivot node in `T`.
|
195
|
+
|
196
|
+
This is a helper method to method :meth:`cographs`.
|
197
|
+
|
198
|
+
A node in `T` is a ``pivot`` if it is not a leaf, it does not induce a
|
199
|
+
maximum partition and it is the first such node in the inverse postorder
|
200
|
+
traversal.
|
201
|
+
|
202
|
+
INPUT:
|
203
|
+
|
204
|
+
- ``T`` -- a ``CoTree``
|
205
|
+
|
206
|
+
EXAMPLES::
|
207
|
+
|
208
|
+
sage: next(graphs.cographs(3, as_graph=True)).vertices() # indirect doctest
|
209
|
+
[0, 1, 2]
|
210
|
+
"""
|
211
|
+
for child in reversed(T.children):
|
212
|
+
pivot = find_pivot(child)
|
213
|
+
if pivot is not None:
|
214
|
+
return pivot
|
215
|
+
|
216
|
+
# Check if T is a pivot
|
217
|
+
i = T.name
|
218
|
+
if (i != 1 and ((i//2 != T.children[0].name) or
|
219
|
+
(i//2 + i % 2 != T.children[1].name))):
|
220
|
+
T.info = 'p' # pivot mark
|
221
|
+
return T
|
222
|
+
return None
|
223
|
+
|
224
|
+
|
225
|
+
def next_tree(T):
|
226
|
+
r"""
|
227
|
+
Check if there is another tree after `T`.
|
228
|
+
|
229
|
+
This is a helper method to method :meth:`cographs`.
|
230
|
+
|
231
|
+
This methods returns ``True`` if there is a tree after `T`, and if so it
|
232
|
+
modifies the input tree `T` that becomes the next tree.
|
233
|
+
|
234
|
+
INPUT:
|
235
|
+
|
236
|
+
- ``T`` -- a ``CoTree``
|
237
|
+
|
238
|
+
EXAMPLES::
|
239
|
+
|
240
|
+
sage: next(graphs.cographs(3, as_graph=True)).vertices() # indirect doctest
|
241
|
+
[0, 1, 2]
|
242
|
+
"""
|
243
|
+
pivot = find_pivot(T)
|
244
|
+
if pivot is None:
|
245
|
+
return False
|
246
|
+
|
247
|
+
# Find the next partition induced by the subtree pivot.
|
248
|
+
# Partitions are represented in ascending order (i.e., `P_i \leq P_{i+1}`)
|
249
|
+
# and we search for the next partition in lexicographic order.
|
250
|
+
partition = [c.name for c in pivot.children]
|
251
|
+
P = AccelAsc_next(partition)
|
252
|
+
# and rebuild the subtree of pivot accordingly
|
253
|
+
rebuild_node(pivot, P)
|
254
|
+
|
255
|
+
x = pivot
|
256
|
+
while x.parent is not None:
|
257
|
+
ancestor = x.parent
|
258
|
+
# Modify the bigger siblings of x (i.e., the siblings placed after
|
259
|
+
# x in the list of children of ancestor)
|
260
|
+
is_bigger_sibling = False
|
261
|
+
for y, this_child in enumerate(ancestor.children):
|
262
|
+
if this_child.info == 'p':
|
263
|
+
is_bigger_sibling = True
|
264
|
+
elif is_bigger_sibling: # true only for bigger siblings of x
|
265
|
+
if x.name == this_child.name:
|
266
|
+
temp = CoTree(x.name)
|
267
|
+
x.copy_tree(temp)
|
268
|
+
ancestor.children[y] = temp # copy subtree T(x) in T(y)
|
269
|
+
temp.parent = ancestor
|
270
|
+
else:
|
271
|
+
P = [1] * ancestor.children[y].name
|
272
|
+
rebuild_node(ancestor.children[y], P)
|
273
|
+
|
274
|
+
# Make the parent of x (if any) the new pivot
|
275
|
+
x.info = None # reset the pivot mark
|
276
|
+
ancestor.info = 'p' # parent gets the pivot mark
|
277
|
+
x = ancestor
|
278
|
+
|
279
|
+
return True
|
280
|
+
|
281
|
+
|
282
|
+
def cographs(n, as_graph=True, immutable=False):
|
283
|
+
r"""
|
284
|
+
Return an iterator over the cographs of order `n`.
|
285
|
+
|
286
|
+
A cograph is a `P_4`-free graph, that is a graph without induced path of
|
287
|
+
order 4. Any cograph may be constructed, starting from the single vertex
|
288
|
+
graph, by a sequence of :meth:`sage.graphs.graph.Graph.join` and
|
289
|
+
:meth:`sage.graphs.generic_graph.GenericGraph.disjoint_union` operations.
|
290
|
+
See the :wikipedia:`Cograph` for more details.
|
291
|
+
|
292
|
+
This method implements the generator of all cographs of order `n` proposed
|
293
|
+
in [JPD2018]_. The algorithm generates one by one every cotree with `n`
|
294
|
+
nodes, and each cotree is generated by using its previous cotree. The time
|
295
|
+
to construct the first cotree is `O(n)` and the time spent between two
|
296
|
+
consecutive outputs is `O(n)`. Hence, the overall complexity of the
|
297
|
+
algorithm is `O(n*M_n)`, where `n` is the number of nodes and `M_n` is the
|
298
|
+
total number of cographs with `n` nodes (see :oeis:`A000084`).
|
299
|
+
|
300
|
+
INPUT:
|
301
|
+
|
302
|
+
- ``n`` -- integer larger or equal to 1
|
303
|
+
|
304
|
+
- ``as_graph`` -- boolean (default: ``True``); whether to return graphs or
|
305
|
+
the tree data structure encoding the graph
|
306
|
+
|
307
|
+
- ``immutable`` -- boolean (default: ``False``); whether to return an
|
308
|
+
immutable or a mutable graph. This parameter is used only when ``as_graph
|
309
|
+
is True``.
|
310
|
+
|
311
|
+
EXAMPLES:
|
312
|
+
|
313
|
+
The output can be either cotrees or graphs::
|
314
|
+
|
315
|
+
sage: for t in graphs.cographs(3, as_graph=False):
|
316
|
+
....: print(t)
|
317
|
+
[ J ( 0 ) ( 1 ) ( 2 ) ]
|
318
|
+
[ J [ U ( 0 ) ( 1 ) ( 2 ) ] ]
|
319
|
+
[ J ( 0 ) [ U ( 1 ) ( 2 ) ] ]
|
320
|
+
[ J [ U ( 0 ) [ J ( 1 ) ( 2 ) ] ] ]
|
321
|
+
sage: for g in graphs.cographs(3, as_graph=True):
|
322
|
+
....: print(g.edges(labels=False, sort=True))
|
323
|
+
[(0, 1), (0, 2), (1, 2)]
|
324
|
+
[]
|
325
|
+
[(0, 1), (0, 2)]
|
326
|
+
[(1, 2)]
|
327
|
+
|
328
|
+
Check that we agree with :oeis:`A000084`::
|
329
|
+
|
330
|
+
sage: [sum(1 for _ in graphs.cographs(n, as_graph=False))
|
331
|
+
....: for n in range(1, 8)]
|
332
|
+
[1, 2, 4, 10, 24, 66, 180]
|
333
|
+
|
334
|
+
TESTS::
|
335
|
+
|
336
|
+
sage: g = next(graphs.cographs(2, as_graph=True, immutable=False))
|
337
|
+
sage: g.is_immutable()
|
338
|
+
False
|
339
|
+
sage: g = next(graphs.cographs(2, as_graph=True, immutable=True))
|
340
|
+
sage: g.is_immutable()
|
341
|
+
True
|
342
|
+
sage: next(graphs.cographs(0))
|
343
|
+
Traceback (most recent call last):
|
344
|
+
...
|
345
|
+
ValueError: parameter n must be at least >= 1
|
346
|
+
"""
|
347
|
+
if n < 1:
|
348
|
+
raise ValueError('parameter n must be at least >= 1')
|
349
|
+
if as_graph:
|
350
|
+
def func(T):
|
351
|
+
return tree_to_graph(T, immutable=immutable)
|
352
|
+
else:
|
353
|
+
def func(T):
|
354
|
+
return T
|
355
|
+
|
356
|
+
if n == 1:
|
357
|
+
T = CoTree('J')
|
358
|
+
B = CoTree('U')
|
359
|
+
B.add_child(CoTree(0))
|
360
|
+
T.add_child(B)
|
361
|
+
yield func(T)
|
362
|
+
return
|
363
|
+
|
364
|
+
# Construct the minimum tree
|
365
|
+
T = CoTree(n)
|
366
|
+
for j in range(n):
|
367
|
+
T.add_child(CoTree(1))
|
368
|
+
|
369
|
+
while True:
|
370
|
+
# T corresponds to 2 cotrees: one with 'U' root and one with 'J' root
|
371
|
+
tree_J = CoTree(T.name)
|
372
|
+
T.copy_tree(tree_J)
|
373
|
+
tree_U = CoTree(T.name)
|
374
|
+
T.copy_tree(tree_U)
|
375
|
+
# tree_J has root 'J'
|
376
|
+
change_label(tree_J, True, [0])
|
377
|
+
# tree 0 has root 'U'
|
378
|
+
change_label(tree_U, False, [0])
|
379
|
+
tree_UU = CoTree('J')
|
380
|
+
tree_UU.add_child(tree_U)
|
381
|
+
yield func(tree_J)
|
382
|
+
yield func(tree_UU)
|
383
|
+
if not next_tree(T):
|
384
|
+
break
|
385
|
+
|
386
|
+
|
387
|
+
def change_label(tree, status, counter):
|
388
|
+
r"""
|
389
|
+
Set the names of the nodes of ``tree``.
|
390
|
+
|
391
|
+
This is a helper method to method :meth:`cographs`.
|
392
|
+
|
393
|
+
The input ``tree`` is such that each node has as label its number of
|
394
|
+
children. This method changes the label of each node so that a parallel
|
395
|
+
node is labeled 'U', a series node is labeled 'J' and a leaf node gets a
|
396
|
+
unique number.
|
397
|
+
|
398
|
+
INPUT:
|
399
|
+
|
400
|
+
- ``tree`` -- the tree to relabel
|
401
|
+
|
402
|
+
- ``status`` -- boolean; used to detect series (``True``) and parallel
|
403
|
+
(``False``) internal nodes
|
404
|
+
|
405
|
+
- ``counter`` -- list; the first integer of the list is used to assign a
|
406
|
+
unique number to the leaves of the tree
|
407
|
+
|
408
|
+
EXAMPLES::
|
409
|
+
|
410
|
+
sage: next(graphs.cographs(4, as_graph=True)).vertices() # indirect doctest
|
411
|
+
[0, 1, 2, 3]
|
412
|
+
"""
|
413
|
+
if tree.name != 1:
|
414
|
+
tree.name = 'J' if status else 'U'
|
415
|
+
else:
|
416
|
+
tree.name = counter[0]
|
417
|
+
counter[0] += 1
|
418
|
+
for child in tree.children:
|
419
|
+
if child is not None:
|
420
|
+
change_label(child, not status, counter)
|
421
|
+
|
422
|
+
|
423
|
+
def tree_to_graph(tree, immutable=False):
|
424
|
+
r"""
|
425
|
+
Return the cograph represented by ``tree``.
|
426
|
+
|
427
|
+
This is a helper method to method :meth:`cographs`.
|
428
|
+
|
429
|
+
EXAMPLES::
|
430
|
+
|
431
|
+
sage: for t in graphs.cographs(3, as_graph=True): # indirect doctest
|
432
|
+
....: print(t.edges(labels=False, sort=True))
|
433
|
+
[(0, 1), (0, 2), (1, 2)]
|
434
|
+
[]
|
435
|
+
[(0, 1), (0, 2)]
|
436
|
+
[(1, 2)]
|
437
|
+
"""
|
438
|
+
from sage.graphs.graph import Graph
|
439
|
+
g = Graph()
|
440
|
+
_tree_to_graph_rec(tree, g)
|
441
|
+
return g.copy(immutable=True) if immutable else g
|
442
|
+
|
443
|
+
|
444
|
+
def _tree_to_graph_rec(tree, g):
|
445
|
+
r"""
|
446
|
+
Add recursively one by one the vertices and edges of ``tree`` to ``g``.
|
447
|
+
|
448
|
+
This is a helper method to method :meth:`tree_to_graph`.
|
449
|
+
|
450
|
+
EXAMPLES::
|
451
|
+
|
452
|
+
sage: for t in graphs.cographs(3, as_graph=True): # indirect doctest
|
453
|
+
....: print(t.edges(labels=False, sort=True))
|
454
|
+
[(0, 1), (0, 2), (1, 2)]
|
455
|
+
[]
|
456
|
+
[(0, 1), (0, 2)]
|
457
|
+
[(1, 2)]
|
458
|
+
"""
|
459
|
+
for child in tree.children:
|
460
|
+
_tree_to_graph_rec(child, g)
|
461
|
+
if tree.name not in ['J', 'U']:
|
462
|
+
tree.info = 'v'
|
463
|
+
g.add_vertex(tree.name)
|
464
|
+
_find_neighbors(tree, g)
|
465
|
+
tree.reset_info()
|
466
|
+
|
467
|
+
|
468
|
+
def _find_neighbors(tree, g):
|
469
|
+
r"""
|
470
|
+
Identify the neighbors of node ``tree`` in ``g`` and add needed edges.
|
471
|
+
|
472
|
+
This is a helper method to method :meth:`tree_to_graph`.
|
473
|
+
|
474
|
+
EXAMPLES::
|
475
|
+
|
476
|
+
sage: for t in graphs.cographs(3, as_graph=True): # indirect doctest
|
477
|
+
....: print(t.edges(labels=False, sort=True))
|
478
|
+
[(0, 1), (0, 2), (1, 2)]
|
479
|
+
[]
|
480
|
+
[(0, 1), (0, 2)]
|
481
|
+
[(1, 2)]
|
482
|
+
"""
|
483
|
+
ancestor = tree.parent
|
484
|
+
ancestor.info = 'v'
|
485
|
+
while ancestor is not None:
|
486
|
+
if ancestor.name == 'J':
|
487
|
+
for sibling in ancestor.children:
|
488
|
+
if sibling != tree and sibling.info != 'v':
|
489
|
+
_add_edge(tree, sibling, g)
|
490
|
+
elif ancestor.name == 'U':
|
491
|
+
ancestor.info = 'v'
|
492
|
+
ancestor = ancestor.parent
|
493
|
+
|
494
|
+
|
495
|
+
def _add_edge(u, v, g):
|
496
|
+
r"""
|
497
|
+
Add an edge in `g` between the nodes associated to the cotrees `u` and `v`.
|
498
|
+
|
499
|
+
This is a helper method to method :meth:`tree_to_graph`.
|
500
|
+
|
501
|
+
If `v` is not a leaf, then the method add edges between `u` and all leaves
|
502
|
+
of the subtree rooted at `v`.
|
503
|
+
|
504
|
+
The method assumes that `u` is a leaf (not tested).
|
505
|
+
|
506
|
+
EXAMPLES::
|
507
|
+
|
508
|
+
sage: for t in graphs.cographs(3, as_graph=True): # indirect doctest
|
509
|
+
....: print(t.edges(labels=False, sort=True))
|
510
|
+
[(0, 1), (0, 2), (1, 2)]
|
511
|
+
[]
|
512
|
+
[(0, 1), (0, 2)]
|
513
|
+
[(1, 2)]
|
514
|
+
"""
|
515
|
+
if v.name in ['J', 'U']:
|
516
|
+
for child in v.children:
|
517
|
+
_add_edge(u, child, g)
|
518
|
+
else:
|
519
|
+
g.add_edge(u.name, v.name)
|
Binary file
|