passagemath-graphs 10.5.10__cp39-cp39-macosx_14_0_arm64.whl → 10.5.43__cp39-cp39-macosx_14_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.
- {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/METADATA +126 -30
- passagemath_graphs-10.5.43.dist-info/RECORD +256 -0
- {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/WHEEL +2 -1
- passagemath_graphs.dylibs/libgmp.10.dylib +0 -0
- sage/all__sagemath_graphs.py +5 -0
- sage/combinat/abstract_tree.py +1 -1
- sage/combinat/binary_tree.py +1 -1
- sage/combinat/cluster_algebra_quiver/all.py +1 -1
- sage/combinat/cluster_algebra_quiver/cluster_seed.py +28 -24
- sage/combinat/cluster_algebra_quiver/interact.py +4 -0
- sage/combinat/designs/MOLS_handbook_data.py +5 -5
- sage/combinat/designs/bibd.py +10 -9
- sage/combinat/designs/covering_array.py +3 -3
- sage/combinat/designs/covering_design.py +2 -1
- sage/combinat/designs/database.py +11 -10
- sage/combinat/designs/designs_pyx.cpython-39-darwin.so +0 -0
- sage/combinat/designs/designs_pyx.pyx +13 -45
- sage/combinat/designs/difference_family.py +6 -6
- sage/combinat/designs/difference_matrices.py +1 -1
- sage/combinat/designs/evenly_distributed_sets.cpython-39-darwin.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +15 -22
- sage/combinat/designs/ext_rep.py +9 -14
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-39-darwin.so +0 -0
- sage/combinat/designs/gen_quadrangles_with_spread.pyx +1 -1
- sage/combinat/designs/group_divisible_designs.py +1 -1
- sage/combinat/designs/incidence_structures.py +8 -8
- sage/combinat/designs/latin_squares.py +1 -1
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +8 -7
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-39-darwin.so +0 -0
- sage/combinat/designs/resolvable_bibd.py +1 -1
- sage/combinat/designs/steiner_quadruple_systems.py +1 -1
- sage/combinat/designs/subhypergraph_search.cpython-39-darwin.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +9 -9
- sage/combinat/finite_state_machine_generators.py +2 -2
- sage/combinat/graph_path.py +3 -3
- sage/combinat/interval_posets.py +10 -10
- sage/combinat/ordered_tree.py +1 -1
- sage/combinat/posets/cartesian_product.py +1 -1
- sage/combinat/posets/d_complete.py +1 -1
- sage/combinat/posets/forest.py +1 -1
- sage/combinat/posets/hasse_cython.cpython-39-darwin.so +0 -0
- sage/combinat/posets/hasse_diagram.py +8 -6
- sage/combinat/posets/incidence_algebras.py +8 -8
- sage/combinat/posets/lattices.py +28 -4
- sage/combinat/posets/linear_extension_iterator.cpython-39-darwin.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +2 -0
- sage/combinat/posets/linear_extensions.py +7 -16
- sage/combinat/posets/moebius_algebra.py +1 -1
- sage/combinat/posets/poset_examples.py +1 -1
- sage/combinat/posets/posets.py +54 -56
- sage/combinat/rooted_tree.py +3 -3
- sage/combinat/tamari_lattices.py +1 -1
- 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/asteroidal_triples.cpython-39-darwin.so +0 -0
- sage/graphs/base/boost_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/boost_graph.pxd +1 -1
- sage/graphs/base/boost_graph.pyx +1 -1
- sage/graphs/base/c_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/c_graph.pxd +4 -4
- sage/graphs/base/c_graph.pyx +270 -184
- sage/graphs/base/dense_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/graph_backends.cpython-39-darwin.so +0 -0
- sage/graphs/base/sparse_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_dense_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_sparse_backend.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_sparse_backend.pyx +93 -6
- sage/graphs/base/static_sparse_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_sparse_graph.pyx +1 -1
- sage/graphs/bipartite_graph.py +0 -1
- sage/graphs/centrality.cpython-39-darwin.so +0 -0
- sage/graphs/centrality.pyx +0 -0
- sage/graphs/comparability.cpython-39-darwin.so +0 -0
- sage/graphs/comparability.pyx +172 -138
- sage/graphs/connectivity.cpython-39-darwin.so +0 -0
- sage/graphs/connectivity.pyx +194 -18
- sage/graphs/convexity_properties.cpython-39-darwin.so +0 -0
- sage/graphs/digraph_generators.py +118 -74
- sage/graphs/distances_all_pairs.cpython-39-darwin.so +0 -0
- sage/graphs/distances_all_pairs.pyx +145 -27
- sage/graphs/edge_connectivity.cpython-39-darwin.so +0 -0
- sage/graphs/generators/basic.py +471 -130
- sage/graphs/generators/distance_regular.cpython-39-darwin.so +0 -0
- sage/graphs/generators/distance_regular.pyx +12 -12
- sage/graphs/generators/families.py +2 -2
- sage/graphs/generators/random.py +8 -13
- sage/graphs/generators/smallgraphs.py +12 -11
- sage/graphs/generic_graph.py +687 -265
- sage/graphs/generic_graph_pyx.cpython-39-darwin.so +0 -0
- sage/graphs/genus.cpython-39-darwin.so +0 -0
- sage/graphs/graph.py +12 -46
- sage/graphs/graph_coloring.cpython-39-darwin.so +0 -0
- sage/graphs/graph_database.py +1 -1
- sage/graphs/graph_decompositions/bandwidth.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/graph_products.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-39-darwin.so +0 -0
- sage/graphs/graph_generators.py +110 -55
- sage/graphs/graph_generators_pyx.cpython-39-darwin.so +0 -0
- sage/graphs/graph_latex.py +1 -1
- sage/graphs/graph_list.py +2 -3
- sage/graphs/graph_plot.py +225 -30
- sage/graphs/hyperbolicity.cpython-39-darwin.so +0 -0
- sage/graphs/independent_sets.cpython-39-darwin.so +0 -0
- sage/graphs/isgci.py +3 -8
- sage/graphs/isoperimetric_inequalities.cpython-39-darwin.so +0 -0
- sage/graphs/line_graph.cpython-39-darwin.so +0 -0
- sage/graphs/matching.py +14 -25
- sage/graphs/matching_covered_graph.py +871 -60
- sage/graphs/orientations.py +190 -134
- sage/graphs/path_enumeration.cpython-39-darwin.so +0 -0
- sage/graphs/path_enumeration.pyx +25 -25
- sage/graphs/spanning_tree.cpython-39-darwin.so +0 -0
- sage/graphs/strongly_regular_db.cpython-39-darwin.so +0 -0
- sage/graphs/strongly_regular_db.pyx +54 -52
- sage/graphs/traversals.cpython-39-darwin.so +0 -0
- sage/graphs/traversals.pyx +114 -46
- sage/graphs/trees.cpython-39-darwin.so +0 -0
- sage/graphs/views.cpython-39-darwin.so +0 -0
- sage/graphs/weakly_chordal.cpython-39-darwin.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-39-darwin.so +0 -0
- sage/knots/free_knotinfo_monoid.py +2 -3
- sage/knots/knot.py +1 -1
- sage/knots/knotinfo.py +4 -4
- sage/knots/link.py +58 -57
- sage/sandpiles/sandpile.py +2 -3
- sage/topology/cell_complex.py +1 -1
- sage/topology/cubical_complex.py +7 -7
- sage/topology/delta_complex.py +4 -4
- sage/topology/simplicial_complex.py +7 -22
- passagemath_graphs-10.5.10.dist-info/RECORD +0 -251
- {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/top_level.txt +0 -0
@@ -71,6 +71,7 @@ AUTHORS:
|
|
71
71
|
``lexicographic_product()`` | Return the lexicographic product of ``self`` and ``other``.
|
72
72
|
``load_afile()`` | Load the matching covered graph specified in the given file into the current object.
|
73
73
|
``merge_vertices()`` | Merge vertices.
|
74
|
+
``minor()`` | Return the vertices of a minor isomorphic to `H` in the current graph.
|
74
75
|
``random_subgraph()`` | Return a random matching covered subgraph containing each vertex with probability ``p``.
|
75
76
|
``save_afile()`` | Save the graph to file in alist format.
|
76
77
|
``strong_product()`` | Return the strong product of ``self`` and ``other``.
|
@@ -82,6 +83,7 @@ AUTHORS:
|
|
82
83
|
``subgraph_search_iterator()`` | Return an iterator over the labelled copies of (matching covered) ``G`` in ``self``.
|
83
84
|
``tensor_product()`` | Return the tensor product of ``self`` and ``other``.
|
84
85
|
``to_undirected()`` | Return an undirected Graph instance of the matching covered graph.
|
86
|
+
``topological_minor()`` | Return a topological `H`-minor from ``self`` if one exists.
|
85
87
|
``transitive_closure()`` | Return the transitive closure of the matching covered graph.
|
86
88
|
``transitive_reduction()`` | Return a transitive reduction of the matching covered graph.
|
87
89
|
``union()`` | Return the union of ``self`` and ``other``.
|
@@ -94,12 +96,10 @@ AUTHORS:
|
|
94
96
|
:delim: |
|
95
97
|
|
96
98
|
``bricks_and_braces()`` | Return the list of (underlying simple graph of) the bricks and braces of the (matching covered) graph.
|
97
|
-
``is_brace()`` | Check if the (matching covered) graph is a brace.
|
98
|
-
``is_brick()`` | Check if the (matching covered) graph is a brick.
|
99
99
|
``number_of_braces()`` | Return the number of braces.
|
100
100
|
``number_of_bricks()`` | Return the number of bricks.
|
101
101
|
``number_of_petersen_bricks()`` | Return the number of Petersen bricks.
|
102
|
-
``tight_cut_decomposition()`` | Return a tight
|
102
|
+
``tight_cut_decomposition()`` | Return a maximal set of laminar nontrivial tight cuts and a corresponding vertex set partition.
|
103
103
|
|
104
104
|
**Removability and ear decomposition**
|
105
105
|
|
@@ -1618,13 +1618,13 @@ class MatchingCoveredGraph(Graph):
|
|
1618
1618
|
|
1619
1619
|
.. SEEALSO::
|
1620
1620
|
|
1621
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops
|
1622
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops
|
1623
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges
|
1624
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices
|
1625
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops
|
1626
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops
|
1627
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
1621
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`
|
1622
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`
|
1623
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`
|
1624
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`
|
1625
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`
|
1626
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`
|
1627
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
1628
1628
|
"""
|
1629
1629
|
if new:
|
1630
1630
|
raise ValueError('loops are not allowed in '
|
@@ -1659,13 +1659,13 @@ class MatchingCoveredGraph(Graph):
|
|
1659
1659
|
|
1660
1660
|
.. SEEALSO::
|
1661
1661
|
|
1662
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops
|
1663
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops
|
1664
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges
|
1665
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices
|
1666
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops
|
1667
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops
|
1668
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
1662
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`
|
1663
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`
|
1664
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`
|
1665
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`
|
1666
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`
|
1667
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`
|
1668
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
1669
1669
|
"""
|
1670
1670
|
return False
|
1671
1671
|
|
@@ -2059,8 +2059,7 @@ class MatchingCoveredGraph(Graph):
|
|
2059
2059
|
|
2060
2060
|
sage: J = G.copy()
|
2061
2061
|
sage: J.delete_vertices(B)
|
2062
|
-
sage: all(len(K)%2 != 0 for K in J.connected_components())
|
2063
|
-
...
|
2062
|
+
sage: all(len(K)%2 != 0 for K in J.connected_components(sort=True))
|
2064
2063
|
True
|
2065
2064
|
|
2066
2065
|
Let `B` be a maximal barrier in a matching covered graph `G` and let
|
@@ -2069,7 +2068,7 @@ class MatchingCoveredGraph(Graph):
|
|
2069
2068
|
`v` is the end of that edge in `V(K)`, then `M \cap E(K)` is a perfect
|
2070
2069
|
matching of `K - v`::
|
2071
2070
|
|
2072
|
-
sage: K = J.subgraph(vertices=(J.connected_components())[0])
|
2071
|
+
sage: K = J.subgraph(vertices=(J.connected_components(sort=True))[0])
|
2073
2072
|
sage: # Let F := \partial_G(K) and T := M \cap F
|
2074
2073
|
sage: F = [edge for edge in G.edge_iterator()
|
2075
2074
|
....: if (edge[0] in K and edge[1] not in K)
|
@@ -2093,7 +2092,7 @@ class MatchingCoveredGraph(Graph):
|
|
2093
2092
|
`G - B` is factor critical::
|
2094
2093
|
|
2095
2094
|
sage: all((K.subgraph(vertices=connected_component)).is_factor_critical()
|
2096
|
-
....: for connected_component in K.connected_components()
|
2095
|
+
....: for connected_component in K.connected_components(sort=True)
|
2097
2096
|
....: )
|
2098
2097
|
True
|
2099
2098
|
|
@@ -2253,13 +2252,13 @@ class MatchingCoveredGraph(Graph):
|
|
2253
2252
|
|
2254
2253
|
.. SEEALSO::
|
2255
2254
|
|
2256
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops
|
2257
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops
|
2258
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges
|
2259
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices
|
2260
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops
|
2261
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops
|
2262
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
2255
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`
|
2256
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`
|
2257
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`
|
2258
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`
|
2259
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`
|
2260
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`
|
2261
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
2263
2262
|
"""
|
2264
2263
|
return False
|
2265
2264
|
|
@@ -2348,6 +2347,820 @@ class MatchingCoveredGraph(Graph):
|
|
2348
2347
|
raise ValueError('algorithm must be set to \'Edmonds\', '
|
2349
2348
|
'\'LP_matching\' or \'LP\'')
|
2350
2349
|
|
2350
|
+
@doc_index('Bricks, braces and tight cut decomposition')
|
2351
|
+
def is_brace(self, coNP_certificate=False):
|
2352
|
+
r"""
|
2353
|
+
Check if the (matching covered) graph is a brace.
|
2354
|
+
|
2355
|
+
A matching covered graph which is free of nontrivial tight cuts is
|
2356
|
+
called a *brace* if it is bipartite. Let `G := (A \cup B, E)` be a
|
2357
|
+
bipartite matching covered graph on six or more vertices. The
|
2358
|
+
following statements are equivalent [LM2024]_:
|
2359
|
+
|
2360
|
+
1. `G` is a brace (aka free of nontrivial tight cuts).
|
2361
|
+
2. `G - a_1 - a_2 - b_1 - b_2` has a perfect matching for any two
|
2362
|
+
distinct vertices `a_1` and `a_2` in `A` and any two distinct
|
2363
|
+
vertices `b_1` and `b_2` in `B`.
|
2364
|
+
3. `G` is two extendable (any two nonadjacent distinct edges can be
|
2365
|
+
extended to some perfect matching of `G`).
|
2366
|
+
4. `|N(X)| \geq |X| + 2`, for all `X ⊂ A` such that `0 < |X| <
|
2367
|
+
|A| - 1`, where `N(S) := \{b \mid (a, b) \in E ∧ a \in S\}` is called
|
2368
|
+
the neighboring set of `S`.
|
2369
|
+
5. `G - a - b` is matching covered, for some perfect matching `M` of
|
2370
|
+
`G` and for each edge `ab` in `M`.
|
2371
|
+
|
2372
|
+
We shall be using the 5th characterization mentioned above in order
|
2373
|
+
to determine whether the provided bipartite matching covered graph
|
2374
|
+
is a brace or not using *M*-alternating tree search [LZ2001]_.
|
2375
|
+
|
2376
|
+
INPUT:
|
2377
|
+
|
2378
|
+
- ``coNP_certificate`` -- boolean (default: ``False``)
|
2379
|
+
|
2380
|
+
OUTPUT:
|
2381
|
+
|
2382
|
+
- If the input matching covered graph is not bipartite, a
|
2383
|
+
:exc:`ValueError` is returned.
|
2384
|
+
|
2385
|
+
- If the input bipartite matching covered graph is a brace, a boolean
|
2386
|
+
``True`` is returned if ``coNP_certificate`` is set to ``False``
|
2387
|
+
otherwise a 5-tuple ``(True, None, None, None, None)`` is returned.
|
2388
|
+
|
2389
|
+
- If the input bipartite matching covered graph is not a brace, a
|
2390
|
+
boolean ``False`` is returned if ``coNP_certificate`` is set to
|
2391
|
+
``False`` otherwise a 5-tuple of
|
2392
|
+
|
2393
|
+
1. a boolean ``False``,
|
2394
|
+
|
2395
|
+
2. a list of edges constituting a nontrivial tight cut (which is a
|
2396
|
+
nontrivial barrier cut)
|
2397
|
+
|
2398
|
+
3. a set of vertices of one of the shores of the nontrivial tight cut
|
2399
|
+
|
2400
|
+
4. a string 'nontrivial tight cut'
|
2401
|
+
|
2402
|
+
5. a set of vertices showing the respective barrier
|
2403
|
+
|
2404
|
+
is returned.
|
2405
|
+
|
2406
|
+
EXAMPLES:
|
2407
|
+
|
2408
|
+
The complete graph on two vertices `K_2` is the smallest brace::
|
2409
|
+
|
2410
|
+
sage: K = graphs.CompleteGraph(2)
|
2411
|
+
sage: G = MatchingCoveredGraph(K)
|
2412
|
+
sage: G.is_brace()
|
2413
|
+
True
|
2414
|
+
|
2415
|
+
The cycle graph on four vertices `C_4` is a brace::
|
2416
|
+
|
2417
|
+
sage: C = graphs.CycleGraph(4)
|
2418
|
+
sage: G = MatchingCoveredGraph(C)
|
2419
|
+
sage: G.is_brace()
|
2420
|
+
True
|
2421
|
+
|
2422
|
+
Each graph that is isomorphic to a biwheel is a brace::
|
2423
|
+
|
2424
|
+
sage: B = graphs.BiwheelGraph(15)
|
2425
|
+
sage: G = MatchingCoveredGraph(B)
|
2426
|
+
sage: G.is_brace()
|
2427
|
+
True
|
2428
|
+
|
2429
|
+
A circular ladder graph of order eight or more on `2n` vertices for
|
2430
|
+
an even `n` is a brace::
|
2431
|
+
|
2432
|
+
sage: n = 10
|
2433
|
+
sage: CL = graphs.CircularLadderGraph(n)
|
2434
|
+
sage: G = MatchingCoveredGraph(CL)
|
2435
|
+
sage: G.is_brace()
|
2436
|
+
True
|
2437
|
+
|
2438
|
+
A moebius ladder graph of order six or more on `2n` vertices for an odd
|
2439
|
+
`n` is a brace::
|
2440
|
+
|
2441
|
+
sage: n = 11
|
2442
|
+
sage: ML = graphs.MoebiusLadderGraph(n)
|
2443
|
+
sage: G = MatchingCoveredGraph(ML)
|
2444
|
+
sage: G.is_brace()
|
2445
|
+
True
|
2446
|
+
|
2447
|
+
Note that the union of the above mentioned four families of braces,
|
2448
|
+
that are:
|
2449
|
+
|
2450
|
+
1. the biwheel graph ``BiwheelGraph(n)``,
|
2451
|
+
2. the circular ladder graph ``CircularLadderGraph(n)`` for even ``n``,
|
2452
|
+
3. the moebius ladder graph ``MoebiusLadderGraph(n)`` for odd ``n``,
|
2453
|
+
|
2454
|
+
is referred to as the *McCuaig* *family* *of* *braces.*
|
2455
|
+
|
2456
|
+
The only simple brace of order six is the complete graph of the same
|
2457
|
+
order, that is `K_{3, 3}`::
|
2458
|
+
|
2459
|
+
sage: L = list(graphs(6,
|
2460
|
+
....: lambda G: G.size() <= 15 and
|
2461
|
+
....: G.is_bipartite())
|
2462
|
+
....: )
|
2463
|
+
sage: L = list(G for G in L if G.is_connected() and
|
2464
|
+
....: G.is_matching_covered()
|
2465
|
+
....: )
|
2466
|
+
sage: M = list(MatchingCoveredGraph(G) for G in L)
|
2467
|
+
sage: B = list(G for G in M if G.is_brace())
|
2468
|
+
sage: K = graphs.CompleteBipartiteGraph(3, 3)
|
2469
|
+
sage: G = MatchingCoveredGraph(K)
|
2470
|
+
sage: next(iter(B)).is_isomorphic(G)
|
2471
|
+
True
|
2472
|
+
|
2473
|
+
The nonplanar `K_{3, 3}`-free brace Heawood graph is the unique cubic
|
2474
|
+
graph of girth six with the fewest number of vertices (that is 14).
|
2475
|
+
Note that by `K_{3, 3}`-free, it shows that the Heawood graph does not
|
2476
|
+
contain a subgraph that is isomophic to a graph obtained by
|
2477
|
+
bisubdivision of `K_{3, 3}`::
|
2478
|
+
|
2479
|
+
sage: K = graphs.CompleteBipartiteGraph(3, 3)
|
2480
|
+
sage: J = graphs.HeawoodGraph()
|
2481
|
+
sage: H = MatchingCoveredGraph(J)
|
2482
|
+
sage: H.is_brace() and not H.is_planar() and \
|
2483
|
+
....: H.is_regular(k=3) and H.girth() == 6
|
2484
|
+
True
|
2485
|
+
|
2486
|
+
Braces of order six or more are 3-connected::
|
2487
|
+
|
2488
|
+
sage: H = graphs.HexahedralGraph()
|
2489
|
+
sage: G = MatchingCoveredGraph(H)
|
2490
|
+
sage: G.is_brace() and G.is_triconnected()
|
2491
|
+
True
|
2492
|
+
|
2493
|
+
Braces of order four or more are 2-extendable::
|
2494
|
+
|
2495
|
+
sage: H = graphs.EllinghamHorton54Graph()
|
2496
|
+
sage: G = MatchingCoveredGraph(H)
|
2497
|
+
sage: G.is_brace()
|
2498
|
+
True
|
2499
|
+
sage: e = next(G.edge_iterator(labels=False)); f = None
|
2500
|
+
sage: for f in G.edge_iterator(labels=False):
|
2501
|
+
....: if not (set(e) & set(f)):
|
2502
|
+
....: break
|
2503
|
+
sage: S = [u for x in [e, f] for u in set(x)]
|
2504
|
+
sage: J = H.copy(); J.delete_vertices(S)
|
2505
|
+
sage: M = Graph(J.matching())
|
2506
|
+
sage: M.add_edges([e, f])
|
2507
|
+
sage: if all(d == 1 for d in M.degree()) and \
|
2508
|
+
....: G.order() == M.order() and \
|
2509
|
+
....: G.order() == 2*M.size():
|
2510
|
+
....: print(f'graph {G} is 2-extendable')
|
2511
|
+
graph Ellingham-Horton 54-graph is 2-extendable
|
2512
|
+
|
2513
|
+
Every edge in a brace of order at least six is removable::
|
2514
|
+
|
2515
|
+
sage: H = graphs.CircularLadderGraph(8)
|
2516
|
+
sage: G = MatchingCoveredGraph(H)
|
2517
|
+
sage: # len(G.removble_edges()) == G.size()
|
2518
|
+
# True
|
2519
|
+
|
2520
|
+
Every brace of order eight has the hexahedral graph as a spanning
|
2521
|
+
subgraph::
|
2522
|
+
|
2523
|
+
sage: H = graphs.HexahedralGraph()
|
2524
|
+
sage: L = list(graphs(8,
|
2525
|
+
....: lambda G: G.size() <= 28 and
|
2526
|
+
....: G.is_bipartite())
|
2527
|
+
....: )
|
2528
|
+
sage: L = list(G for G in L if G.is_connected() and
|
2529
|
+
....: G.is_matching_covered()
|
2530
|
+
....: )
|
2531
|
+
sage: M = list(MatchingCoveredGraph(G) for G in L)
|
2532
|
+
sage: B = list(G for G in M if G.is_brace())
|
2533
|
+
sage: C = list(G for G in M if Graph(G).subgraph_search(H) is not None)
|
2534
|
+
sage: B == C
|
2535
|
+
True
|
2536
|
+
|
2537
|
+
For every brace `G[A, B]` of order at least six, the graph
|
2538
|
+
`G - a_1 - a_2 - b_1 - b_2` has a perfect matching for any two distinct
|
2539
|
+
vertices `a_1` and `a_2` in `A` and any two distinct vertices `b_1` and
|
2540
|
+
`b_2` in `B`::
|
2541
|
+
|
2542
|
+
sage: H = graphs.CompleteBipartiteGraph(10, 10)
|
2543
|
+
sage: G = MatchingCoveredGraph(H)
|
2544
|
+
sage: G.is_brace()
|
2545
|
+
True
|
2546
|
+
sage: S = [0, 1, 10, 12]
|
2547
|
+
sage: G.delete_vertices(S)
|
2548
|
+
sage: G.has_perfect_matching()
|
2549
|
+
True
|
2550
|
+
|
2551
|
+
For a brace `G[A, B]` of order six or more, `|N(X)| \geq |X| + 2`, for
|
2552
|
+
all `X \subset A` such that `0 < |X| <|A| - 1`, where
|
2553
|
+
`N(S) := \{b | (a, b) \in E \^ a \in S\}` is called the neighboring set
|
2554
|
+
of `S`::
|
2555
|
+
|
2556
|
+
sage: H = graphs.MoebiusLadderGraph(15)
|
2557
|
+
sage: G = MatchingCoveredGraph(H)
|
2558
|
+
sage: G.is_brace()
|
2559
|
+
True
|
2560
|
+
sage: A, _ = G.bipartite_sets()
|
2561
|
+
sage: # needs random
|
2562
|
+
sage: X = random.sample(list(A), random.randint(1, len(A) - 1))
|
2563
|
+
sage: N = {v for u in X for v in G.neighbor_iterator(u)}
|
2564
|
+
sage: len(N) >= len(X) + 2
|
2565
|
+
True
|
2566
|
+
|
2567
|
+
For a brace `G` of order four or more with a perfect matching `M`, the
|
2568
|
+
graph `G - a - b` is matching covered for each edge `(a, b)` in `M`::
|
2569
|
+
|
2570
|
+
sage: H = graphs.HeawoodGraph()
|
2571
|
+
sage: G = MatchingCoveredGraph(H)
|
2572
|
+
sage: G.is_brace()
|
2573
|
+
True
|
2574
|
+
sage: M = G.get_matching()
|
2575
|
+
sage: L = []
|
2576
|
+
sage: for a, b, *_ in M:
|
2577
|
+
....: J = G.copy(); J.delete_vertices([a, b])
|
2578
|
+
....: if J.is_matching_covered():
|
2579
|
+
....: L.append(J)
|
2580
|
+
sage: len(L) == len(M)
|
2581
|
+
True
|
2582
|
+
|
2583
|
+
A cycle graph of order six or more is a bipartite matching covered
|
2584
|
+
graph, but is not a brace::
|
2585
|
+
|
2586
|
+
sage: C = graphs.CycleGraph(10)
|
2587
|
+
sage: G = MatchingCoveredGraph(C)
|
2588
|
+
sage: G.is_brace()
|
2589
|
+
False
|
2590
|
+
|
2591
|
+
A ladder graph of order six or more is a bipartite matching covered
|
2592
|
+
graph, that is not a brace. The tight cut decomposition of a ladder
|
2593
|
+
graph produces a list graphs the underlying graph of each of which
|
2594
|
+
is isomorphic to a 4-cycle::
|
2595
|
+
|
2596
|
+
sage: L = graphs.LadderGraph(10)
|
2597
|
+
sage: G = MatchingCoveredGraph(L)
|
2598
|
+
sage: G.is_brace()
|
2599
|
+
False
|
2600
|
+
|
2601
|
+
One may set the ``coNP_certificate`` to be ``True``::
|
2602
|
+
|
2603
|
+
sage: H = graphs.HexahedralGraph()
|
2604
|
+
sage: G = MatchingCoveredGraph(H)
|
2605
|
+
sage: G.is_brace(coNP_certificate=True)
|
2606
|
+
(True, None, None, None, None)
|
2607
|
+
sage: C = graphs.CycleGraph(6)
|
2608
|
+
sage: D = MatchingCoveredGraph(C)
|
2609
|
+
sage: is_brace, nontrivial_tight_cut, nontrivial_odd_component, \
|
2610
|
+
....: nontrivial_tight_cut_variant, cut_identifier = \
|
2611
|
+
....: D.is_brace(coNP_certificate=True)
|
2612
|
+
sage: is_brace is False
|
2613
|
+
True
|
2614
|
+
sage: J = C.subgraph(vertices=nontrivial_odd_component)
|
2615
|
+
sage: J.is_isomorphic(graphs.PathGraph(3))
|
2616
|
+
True
|
2617
|
+
sage: len(nontrivial_tight_cut) == 2
|
2618
|
+
True
|
2619
|
+
sage: nontrivial_tight_cut_variant
|
2620
|
+
'nontrivial barrier cut'
|
2621
|
+
sage: # Corresponding barrier
|
2622
|
+
sage: cut_identifier == {a for u, v, *_ in nontrivial_tight_cut for a in [u, v] \
|
2623
|
+
....: if a not in nontrivial_odd_component}
|
2624
|
+
True
|
2625
|
+
sage: for u, v, *_ in nontrivial_tight_cut:
|
2626
|
+
....: assert (u in nontrivial_odd_component and v not in nontrivial_odd_component)
|
2627
|
+
sage: L = graphs.LadderGraph(3) # A ladder graph with two constituent braces
|
2628
|
+
sage: G = MatchingCoveredGraph(L)
|
2629
|
+
sage: is_brace, nontrivial_tight_cut, nontrivial_odd_component, cut_variant, cut_identifier = \
|
2630
|
+
....: G.is_brace(coNP_certificate=True)
|
2631
|
+
sage: is_brace is False
|
2632
|
+
True
|
2633
|
+
sage: G1 = L.copy()
|
2634
|
+
sage: G1.merge_vertices(list(nontrivial_odd_component))
|
2635
|
+
sage: G1.to_simple().is_isomorphic(graphs.CycleGraph(4))
|
2636
|
+
True
|
2637
|
+
sage: G2 = L.copy()
|
2638
|
+
sage: G2.merge_vertices([v for v in G if v not in nontrivial_odd_component])
|
2639
|
+
sage: G2.to_simple().is_isomorphic(graphs.CycleGraph(4))
|
2640
|
+
True
|
2641
|
+
sage: cut_variant
|
2642
|
+
'nontrivial barrier cut'
|
2643
|
+
sage: cut_identifier == {a for u, v, *_ in nontrivial_tight_cut for a in [u, v] \
|
2644
|
+
....: if a not in nontrivial_odd_component}
|
2645
|
+
True
|
2646
|
+
sage: H = graphs.CompleteBipartiteGraph(3, 3)
|
2647
|
+
sage: H.delete_edge(0, 3)
|
2648
|
+
sage: G = MatchingCoveredGraph(H)
|
2649
|
+
sage: G.is_brace(coNP_certificate=True)
|
2650
|
+
(False,
|
2651
|
+
[(4, 1, None), (5, 1, None), (4, 2, None), (5, 2, None)],
|
2652
|
+
{0, 4, 5},
|
2653
|
+
'nontrivial barrier cut',
|
2654
|
+
{1, 2})
|
2655
|
+
|
2656
|
+
If the input matching covered graph is nonbipartite, a
|
2657
|
+
:exc:`ValueError` is thrown::
|
2658
|
+
|
2659
|
+
sage: K4 = graphs.CompleteGraph(4)
|
2660
|
+
sage: G = MatchingCoveredGraph(K4)
|
2661
|
+
sage: G.is_brace()
|
2662
|
+
Traceback (most recent call last):
|
2663
|
+
...
|
2664
|
+
ValueError: the input graph is not bipartite
|
2665
|
+
sage: P = graphs.PetersenGraph()
|
2666
|
+
sage: H = MatchingCoveredGraph(P)
|
2667
|
+
sage: H.is_brace(coNP_certificate=True)
|
2668
|
+
Traceback (most recent call last):
|
2669
|
+
...
|
2670
|
+
ValueError: the input graph is not bipartite
|
2671
|
+
|
2672
|
+
.. SEEALSO::
|
2673
|
+
|
2674
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.is_brick`
|
2675
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.bricks_and_braces`
|
2676
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_braces`
|
2677
|
+
"""
|
2678
|
+
if not self.is_bipartite():
|
2679
|
+
raise ValueError('the input graph is not bipartite')
|
2680
|
+
|
2681
|
+
if self.order() < 6:
|
2682
|
+
return (True, None, None, None, None) if coNP_certificate else True
|
2683
|
+
|
2684
|
+
A, B = self.bipartite_sets()
|
2685
|
+
matching = set(self.get_matching())
|
2686
|
+
matching_neighbor = {x: y for u, v, *_ in matching for x, y in [(u, v), (v, u)]}
|
2687
|
+
|
2688
|
+
for e in matching:
|
2689
|
+
u, v, *_ = e
|
2690
|
+
|
2691
|
+
# Let G denote the undirected graph self, and
|
2692
|
+
# let the graph H(e) := G — u — v
|
2693
|
+
H = Graph(self, multiedges=False)
|
2694
|
+
H.delete_vertices([u, v])
|
2695
|
+
|
2696
|
+
if not H.is_connected() or not H.is_matching_covered(list(matching - set([e]))):
|
2697
|
+
if not coNP_certificate:
|
2698
|
+
return False
|
2699
|
+
|
2700
|
+
# Construct the digraph D(e)(A ∪ B, F) defined as follows:
|
2701
|
+
from sage.graphs.digraph import DiGraph
|
2702
|
+
D = DiGraph()
|
2703
|
+
|
2704
|
+
# For each edge (a, b) in E(H(e)) ∩ M with a in A, b —> a in D(e).
|
2705
|
+
# For each edge (a, b) in E(H(e)) with a in A, a —> b in D(e).
|
2706
|
+
for a, b in H.edge_iterator(labels=False, sort_vertices=True):
|
2707
|
+
|
2708
|
+
if a in B:
|
2709
|
+
a, b = b, a
|
2710
|
+
|
2711
|
+
D.add_edge((a, b))
|
2712
|
+
if matching_neighbor[a] == b:
|
2713
|
+
D.add_edge((b, a))
|
2714
|
+
|
2715
|
+
# H(e) is matching covered iff D(e) is strongly connected.
|
2716
|
+
# Check if D(e) is strongly connected using Kosaraju's algorithm
|
2717
|
+
def dfs(x, visited, neighbor_iterator):
|
2718
|
+
stack = [x] # a stack of xertices
|
2719
|
+
|
2720
|
+
while stack:
|
2721
|
+
x = stack.pop()
|
2722
|
+
visited.add(x)
|
2723
|
+
|
2724
|
+
for y in neighbor_iterator(x):
|
2725
|
+
if y not in visited:
|
2726
|
+
stack.append(y)
|
2727
|
+
|
2728
|
+
root = next(D.vertex_iterator())
|
2729
|
+
|
2730
|
+
visited_in = set()
|
2731
|
+
dfs(root, visited_in, D.neighbor_in_iterator)
|
2732
|
+
|
2733
|
+
# Since D(e) is not strongly connected, it has a directed cut T(e).
|
2734
|
+
# Note that by definition of D(e), it follows that T(e) ⊆ E(H(e)) — M.
|
2735
|
+
# Thus, T(e) is a cut of H(e), which has a shore X such that every edge of T(e) is
|
2736
|
+
# incident with a vertex in X ∩ B.
|
2737
|
+
|
2738
|
+
# Moreover, M — e is a perfect matching of H(e), and thus, |X ∩ A| = |X ∩ B|
|
2739
|
+
# Consequently, Y := X + v is a shore of a nontrivial tight cut T of G
|
2740
|
+
|
2741
|
+
if len(visited_in) != D.order():
|
2742
|
+
X = visited_in
|
2743
|
+
else:
|
2744
|
+
X = set()
|
2745
|
+
dfs(root, X, D.neighbor_out_iterator)
|
2746
|
+
|
2747
|
+
color_class = None
|
2748
|
+
|
2749
|
+
for a, b in H.edge_iterator(labels=False, sort_vertices=True):
|
2750
|
+
if (a in X) ^ (b in X):
|
2751
|
+
x = a if a in A else b
|
2752
|
+
color_class = x not in X
|
2753
|
+
break
|
2754
|
+
|
2755
|
+
# Obtain the color class Z ∈ {A, B} such that X ∩ Z is a vertex cover for T(e)
|
2756
|
+
# Thus, obtain Y := X + v
|
2757
|
+
X.add(u if (not color_class and u in A) or (color_class and u in B) or (color_class is None) else v)
|
2758
|
+
|
2759
|
+
# Compute the nontrivial tight cut C := ∂(Y)
|
2760
|
+
C = [(x, y, w) if x in X else (y, x, w)
|
2761
|
+
for x, y, w in self.edge_iterator(sort_vertices=True)
|
2762
|
+
if (x in X) ^ (y in X)]
|
2763
|
+
|
2764
|
+
# Obtain the barrier Z
|
2765
|
+
Z = None
|
2766
|
+
|
2767
|
+
if (u in X and u in A) or (v in X and v in A):
|
2768
|
+
Z = {b for b in B if b not in X}
|
2769
|
+
else:
|
2770
|
+
Z = {a for a in A if a not in X}
|
2771
|
+
|
2772
|
+
return (False, C, set(X), 'nontrivial barrier cut', Z)
|
2773
|
+
|
2774
|
+
return (True, None, None, None, None) if coNP_certificate else True
|
2775
|
+
|
2776
|
+
@doc_index('Bricks, braces and tight cut decomposition')
|
2777
|
+
def is_brick(self, coNP_certificate=False):
|
2778
|
+
r"""
|
2779
|
+
Check if the (matching covered) graph is a brick.
|
2780
|
+
|
2781
|
+
A matching covered graph which is free of nontrivial tight cuts is
|
2782
|
+
called a *brick* if it is nonbipartite. A nonbipartite matching covered
|
2783
|
+
graph is a brick if and only if it is 3-connected and bicritical
|
2784
|
+
[LM2024]_.
|
2785
|
+
|
2786
|
+
INPUT:
|
2787
|
+
|
2788
|
+
- ``coNP_certificate`` -- boolean (default: ``False``)
|
2789
|
+
|
2790
|
+
OUTPUT:
|
2791
|
+
|
2792
|
+
- If the input matching covered graph is bipartite, a :exc:`ValueError`
|
2793
|
+
is returned.
|
2794
|
+
|
2795
|
+
- If the input nonbipartite matching covered graph is a brick, a
|
2796
|
+
boolean ``True`` is returned if ``coNP_certificate`` is set to
|
2797
|
+
``False``, otherwise a 5-tuple ``(True, None, None, None, None)`` is
|
2798
|
+
returned.
|
2799
|
+
|
2800
|
+
- If the input nonbipartite matching covered graph is not a brick, a
|
2801
|
+
boolean ``False`` is returned if ``coNP_certificate`` is set to
|
2802
|
+
``False``.
|
2803
|
+
|
2804
|
+
- If ``coNP_certificate`` is set to ``True`` and the input nonbipartite
|
2805
|
+
graph is not a brick, a 5-tuple of
|
2806
|
+
|
2807
|
+
1. a boolean ``False``,
|
2808
|
+
|
2809
|
+
2. a list of lists of edges, each list constituting a nontrivial
|
2810
|
+
tight cut collectively representing a laminar tight cut,
|
2811
|
+
|
2812
|
+
3. a list of set of vertices of one of the shores of those respective
|
2813
|
+
nontrivial tight cuts:
|
2814
|
+
|
2815
|
+
#. In case of nontrivial barrier cuts, each of the shores is a
|
2816
|
+
nontrivial odd component with respect to a nontrivial barrier,
|
2817
|
+
thus the returned list forms mutually exclusive collection of
|
2818
|
+
(odd) sets.
|
2819
|
+
|
2820
|
+
#. Otherwise each of the nontrivial tight cuts is a 2-separation
|
2821
|
+
cut, each of the shores form a subset sequence, with the
|
2822
|
+
`i` th shore being a proper subset of the `i + 1` th shore.
|
2823
|
+
|
2824
|
+
4. a string showing whether the nontrivial tight cuts are barrier
|
2825
|
+
cuts (if the string is 'nontrivial barrier cut'), or 2-separation
|
2826
|
+
cuts (if the string is 'nontrivial 2-separation cut')
|
2827
|
+
|
2828
|
+
5. a set of vertices showing the respective barrier if the
|
2829
|
+
nontrivial tight cuts are barrier cuts, or otherwise
|
2830
|
+
a set of two vertices constituting the corresponding
|
2831
|
+
two vertex cut (in this case the nontrivial tight cuts are
|
2832
|
+
2-separation cuts)
|
2833
|
+
|
2834
|
+
is returned.
|
2835
|
+
|
2836
|
+
EXAMPLES:
|
2837
|
+
|
2838
|
+
The complete graph on four vertices `K_4` is the smallest brick::
|
2839
|
+
|
2840
|
+
sage: K = graphs.CompleteGraph(4)
|
2841
|
+
sage: G = MatchingCoveredGraph(K)
|
2842
|
+
sage: G.is_brick()
|
2843
|
+
True
|
2844
|
+
|
2845
|
+
The triangular cicular ladder (a graph on six vertices), aka
|
2846
|
+
`\overline{C_6}` is a brick::
|
2847
|
+
|
2848
|
+
sage: C6Bar = graphs.CircularLadderGraph(3)
|
2849
|
+
sage: G = MatchingCoveredGraph(C6Bar)
|
2850
|
+
sage: G.is_brick()
|
2851
|
+
True
|
2852
|
+
|
2853
|
+
Each of Petersen graph, Bicorn graph, Tricorn graph, Cubeplex graph,
|
2854
|
+
Twinplex graph, Wagner graph is a brick::
|
2855
|
+
|
2856
|
+
sage: MatchingCoveredGraph(graphs.PetersenGraph()).is_brick() and \
|
2857
|
+
....: MatchingCoveredGraph(graphs.StaircaseGraph(4)).is_brick() and \
|
2858
|
+
....: MatchingCoveredGraph(graphs.TricornGraph()).is_brick() and \
|
2859
|
+
....: MatchingCoveredGraph(graphs.CubeplexGraph()).is_brick() and \
|
2860
|
+
....: MatchingCoveredGraph(graphs.TwinplexGraph()).is_brick() and \
|
2861
|
+
....: MatchingCoveredGraph(graphs.WagnerGraph()).is_brick()
|
2862
|
+
True
|
2863
|
+
|
2864
|
+
The Murty graph is the smallest simple brick that is not odd-intercyclic::
|
2865
|
+
|
2866
|
+
sage: M = graphs.MurtyGraph()
|
2867
|
+
sage: G = MatchingCoveredGraph(M)
|
2868
|
+
sage: G.is_brick()
|
2869
|
+
True
|
2870
|
+
|
2871
|
+
A circular ladder graph of order six or more on `2n` vertices for an
|
2872
|
+
odd `n` is a brick::
|
2873
|
+
|
2874
|
+
sage: n = 11
|
2875
|
+
sage: CL = graphs.CircularLadderGraph(n)
|
2876
|
+
sage: G = MatchingCoveredGraph(CL)
|
2877
|
+
sage: G.is_brick()
|
2878
|
+
True
|
2879
|
+
|
2880
|
+
A moebius ladder graph of order eight or more on `2n` vertices for an
|
2881
|
+
even `n` is a brick::
|
2882
|
+
|
2883
|
+
sage: n = 10
|
2884
|
+
sage: ML = graphs.MoebiusLadderGraph(n)
|
2885
|
+
sage: G = MatchingCoveredGraph(ML)
|
2886
|
+
sage: G.is_brick()
|
2887
|
+
True
|
2888
|
+
|
2889
|
+
A wheel graph of an even order is a brick::
|
2890
|
+
|
2891
|
+
sage: W = graphs.WheelGraph(10)
|
2892
|
+
sage: G = MatchingCoveredGraph(W)
|
2893
|
+
sage: G.is_brick()
|
2894
|
+
True
|
2895
|
+
|
2896
|
+
A graph that is isomorphic to a truncated biwheel graph is a brick::
|
2897
|
+
|
2898
|
+
sage: TB = graphs.TruncatedBiwheelGraph(15)
|
2899
|
+
sage: G = MatchingCoveredGraph(TB)
|
2900
|
+
sage: G.is_brick()
|
2901
|
+
True
|
2902
|
+
|
2903
|
+
Each of the graphs in the staircase graph family with order eight or
|
2904
|
+
more is a brick::
|
2905
|
+
|
2906
|
+
sage: ST = graphs.StaircaseGraph(9)
|
2907
|
+
sage: G = MatchingCoveredGraph(ST)
|
2908
|
+
sage: G.is_brick()
|
2909
|
+
True
|
2910
|
+
|
2911
|
+
Bricks are 3-connected::
|
2912
|
+
|
2913
|
+
sage: P = graphs.PetersenGraph()
|
2914
|
+
sage: G = MatchingCoveredGraph(P)
|
2915
|
+
sage: G.is_brick()
|
2916
|
+
True
|
2917
|
+
sage: G.is_triconnected()
|
2918
|
+
True
|
2919
|
+
|
2920
|
+
Bricks are bicritical::
|
2921
|
+
|
2922
|
+
sage: P = graphs.PetersenGraph()
|
2923
|
+
sage: G = MatchingCoveredGraph(P)
|
2924
|
+
sage: G.is_brick()
|
2925
|
+
True
|
2926
|
+
sage: G.is_bicritical()
|
2927
|
+
True
|
2928
|
+
|
2929
|
+
Examples of nonbipartite matching covered graphs that are not
|
2930
|
+
bricks::
|
2931
|
+
|
2932
|
+
sage: H = Graph([
|
2933
|
+
....: (0, 3), (0, 4), (0, 7),
|
2934
|
+
....: (1, 3), (1, 5), (1, 7),
|
2935
|
+
....: (2, 3), (2, 6), (2, 7),
|
2936
|
+
....: (4, 5), (4, 6), (5, 6)
|
2937
|
+
....: ])
|
2938
|
+
sage: G = MatchingCoveredGraph(H)
|
2939
|
+
sage: G.is_bipartite()
|
2940
|
+
False
|
2941
|
+
sage: G.is_bicritical()
|
2942
|
+
False
|
2943
|
+
sage: G.is_triconnected()
|
2944
|
+
True
|
2945
|
+
sage: G.is_brick()
|
2946
|
+
False
|
2947
|
+
sage: H = Graph([
|
2948
|
+
....: (0, 1), (0, 2), (0, 3), (0, 4), (1, 2),
|
2949
|
+
....: (1, 5), (2, 5), (3, 4), (3, 5), (4, 5)
|
2950
|
+
....: ])
|
2951
|
+
sage: G = MatchingCoveredGraph(H)
|
2952
|
+
sage: G.is_bipartite()
|
2953
|
+
False
|
2954
|
+
sage: G.is_bicritical()
|
2955
|
+
True
|
2956
|
+
sage: G.is_triconnected()
|
2957
|
+
False
|
2958
|
+
sage: G.is_brick()
|
2959
|
+
False
|
2960
|
+
|
2961
|
+
One may set the ``coNP_certificate`` to be ``True``::
|
2962
|
+
|
2963
|
+
sage: K4 = graphs.CompleteGraph(4)
|
2964
|
+
sage: G = MatchingCoveredGraph(K4)
|
2965
|
+
sage: G.is_brick(coNP_certificate=True)
|
2966
|
+
(True, None, None, None, None)
|
2967
|
+
sage: # K(4) ⊙ K(3, 3) is nonbipartite but not a brick
|
2968
|
+
sage: H = graphs.MurtyGraph(); H.delete_edge(0, 1)
|
2969
|
+
sage: G = MatchingCoveredGraph(H)
|
2970
|
+
sage: G.is_brick(coNP_certificate=True)
|
2971
|
+
(False, [[(5, 2, None), (6, 3, None), (7, 4, None)]], [{5, 6, 7}],
|
2972
|
+
'nontrivial barrier cut', {2, 3, 4})
|
2973
|
+
sage: H = Graph([
|
2974
|
+
....: (0, 12), (0, 13), (0, 15), (1, 4), (1, 13), (1, 14),
|
2975
|
+
....: (1, 19), (2, 4), (2, 13), (2, 14), (2, 17), (3, 9),
|
2976
|
+
....: (3, 13), (3, 16), (3, 21), (4, 6), (4, 7), (5, 7),
|
2977
|
+
....: (5, 8), (5, 12), (6, 8), (6, 11), (7, 10), (8, 9),
|
2978
|
+
....: (9, 10), (10, 11), (11, 12), (14, 15), (14, 16), (15, 16),
|
2979
|
+
....: (17, 18), (17, 21), (18, 19), (18, 20), (19, 20), (20, 21)
|
2980
|
+
....: ])
|
2981
|
+
sage: G = MatchingCoveredGraph(H)
|
2982
|
+
sage: G.is_brick(coNP_certificate=True)
|
2983
|
+
(False,
|
2984
|
+
[[(12, 0, None), (4, 1, None), (4, 2, None), (9, 3, None)],
|
2985
|
+
[(19, 1, None), (17, 2, None), (21, 3, None)],
|
2986
|
+
[(15, 0, None), (14, 1, None), (14, 2, None), (16, 3, None)]],
|
2987
|
+
[{4, 5, 6, 7, 8, 9, 10, 11, 12}, {17, 18, 19, 20, 21}, {14, 15, 16}],
|
2988
|
+
'nontrivial barrier cut', {0, 1, 2, 3})
|
2989
|
+
sage: J = Graph([
|
2990
|
+
....: (0, 1), (0, 2), (0, 3), (0, 4), (0, 5),
|
2991
|
+
....: (0, 6), (0, 7), (0, 8), (0, 9), (0, 10),
|
2992
|
+
....: (1, 2), (1, 11), (2, 11), (3, 4), (3, 11),
|
2993
|
+
....: (4, 11), (5, 6), (5, 11), (6, 11), (7, 8),
|
2994
|
+
....: (7, 11), (8, 11), (9, 10), (9, 11), (10, 11)
|
2995
|
+
....: ])
|
2996
|
+
sage: G = MatchingCoveredGraph(J)
|
2997
|
+
sage: G.is_brick(coNP_certificate=True)
|
2998
|
+
(False,
|
2999
|
+
[[(0, 3, None),
|
3000
|
+
(0, 4, None),
|
3001
|
+
(0, 5, None),
|
3002
|
+
(0, 6, None),
|
3003
|
+
(0, 7, None),
|
3004
|
+
(0, 8, None),
|
3005
|
+
(0, 9, None),
|
3006
|
+
(0, 10, None),
|
3007
|
+
(1, 11, None),
|
3008
|
+
(2, 11, None)],
|
3009
|
+
[(0, 5, None),
|
3010
|
+
(0, 6, None),
|
3011
|
+
(0, 7, None),
|
3012
|
+
(0, 8, None),
|
3013
|
+
(0, 9, None),
|
3014
|
+
(0, 10, None),
|
3015
|
+
(1, 11, None),
|
3016
|
+
(2, 11, None),
|
3017
|
+
(3, 11, None),
|
3018
|
+
(4, 11, None)],
|
3019
|
+
[(0, 7, None),
|
3020
|
+
(0, 8, None),
|
3021
|
+
(0, 9, None),
|
3022
|
+
(0, 10, None),
|
3023
|
+
(1, 11, None),
|
3024
|
+
(2, 11, None),
|
3025
|
+
(3, 11, None),
|
3026
|
+
(4, 11, None),
|
3027
|
+
(5, 11, None),
|
3028
|
+
(6, 11, None)],
|
3029
|
+
[(0, 9, None),
|
3030
|
+
(0, 10, None),
|
3031
|
+
(1, 11, None),
|
3032
|
+
(2, 11, None),
|
3033
|
+
(3, 11, None),
|
3034
|
+
(4, 11, None),
|
3035
|
+
(5, 11, None),
|
3036
|
+
(6, 11, None),
|
3037
|
+
(7, 11, None),
|
3038
|
+
(8, 11, None)]],
|
3039
|
+
[{0, 1, 2},
|
3040
|
+
{0, 1, 2, 3, 4},
|
3041
|
+
{0, 1, 2, 3, 4, 5, 6},
|
3042
|
+
{0, 1, 2, 3, 4, 5, 6, 7, 8}],
|
3043
|
+
'nontrivial 2-separation cut',
|
3044
|
+
{0, 11})
|
3045
|
+
|
3046
|
+
If the input matching covered graph is bipartite, a
|
3047
|
+
:exc:`ValueError` is thrown::
|
3048
|
+
|
3049
|
+
sage: H = graphs.HexahedralGraph()
|
3050
|
+
sage: G = MatchingCoveredGraph(H)
|
3051
|
+
sage: G.is_brick()
|
3052
|
+
Traceback (most recent call last):
|
3053
|
+
...
|
3054
|
+
ValueError: the input graph is bipartite
|
3055
|
+
sage: J = graphs.HeawoodGraph()
|
3056
|
+
sage: G = MatchingCoveredGraph(J)
|
3057
|
+
sage: G.is_brick(coNP_certificate=True)
|
3058
|
+
Traceback (most recent call last):
|
3059
|
+
...
|
3060
|
+
ValueError: the input graph is bipartite
|
3061
|
+
|
3062
|
+
.. SEEALSO::
|
3063
|
+
|
3064
|
+
- :meth:`~sage.graphs.graph.Graph.is_bicritical`
|
3065
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.is_brace`
|
3066
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.bricks_and_braces`
|
3067
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_bricks`
|
3068
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_petersen_bricks`
|
3069
|
+
"""
|
3070
|
+
if self.is_bipartite():
|
3071
|
+
raise ValueError('the input graph is bipartite')
|
3072
|
+
|
3073
|
+
# Check if G is bicritical
|
3074
|
+
bicritical, certificate = self.is_bicritical(coNP_certificate=True)
|
3075
|
+
|
3076
|
+
if not bicritical:
|
3077
|
+
if not coNP_certificate:
|
3078
|
+
return False
|
3079
|
+
|
3080
|
+
# G has a pair of vertices u, v such that G - u - v is not matching
|
3081
|
+
# covered, thus has a nontrivial barrier B containing both u and v.
|
3082
|
+
u, _ = certificate
|
3083
|
+
B = self.maximal_barrier(u)
|
3084
|
+
|
3085
|
+
H = Graph(self)
|
3086
|
+
H.delete_vertices(B)
|
3087
|
+
|
3088
|
+
# Let K be a nontrivial odd component of H := G - B. Note that
|
3089
|
+
# there exists at least one such K since G is nonbipartite
|
3090
|
+
nontrivial_odd_components = [
|
3091
|
+
set(component) for component in H.connected_components(sort=True)
|
3092
|
+
if len(component) % 2 and len(component) > 1
|
3093
|
+
]
|
3094
|
+
|
3095
|
+
# Find a laminar set of nontrivial barrier cuts
|
3096
|
+
C = [[(u, v, w) if u in nontrivial_odd_component else (v, u, w)
|
3097
|
+
for u, v, w in self.edge_iterator()
|
3098
|
+
if (u in nontrivial_odd_component) ^ (v in nontrivial_odd_component)]
|
3099
|
+
for nontrivial_odd_component in nontrivial_odd_components]
|
3100
|
+
|
3101
|
+
return (False, C, nontrivial_odd_components, 'nontrivial barrier cut', B)
|
3102
|
+
|
3103
|
+
# Check if G is 3-connected
|
3104
|
+
if self.is_triconnected():
|
3105
|
+
return (True, None, None, None, None) if coNP_certificate else True
|
3106
|
+
|
3107
|
+
# G has a 2-vertex cut
|
3108
|
+
# Compute the SPQR-tree decomposition
|
3109
|
+
spqr_tree = self.spqr_tree()
|
3110
|
+
two_vertex_cut = []
|
3111
|
+
|
3112
|
+
# Check for 2-vertex cuts in a P node
|
3113
|
+
# Since the graph is matching covered, it is free of cut vertices
|
3114
|
+
# It can be shown using counting arguments that the spqr tree
|
3115
|
+
# decomposition for a bicritical graph, that is 2-connected but not
|
3116
|
+
# 3-connected, is free of 'S' nodes
|
3117
|
+
for u in spqr_tree:
|
3118
|
+
if u[0] == 'P':
|
3119
|
+
two_vertex_cut.extend(u[1])
|
3120
|
+
break
|
3121
|
+
|
3122
|
+
# If no 2-vertex cut found, look for R nodes
|
3123
|
+
if not two_vertex_cut:
|
3124
|
+
from collections import Counter
|
3125
|
+
R_frequency = Counter()
|
3126
|
+
|
3127
|
+
for t, g in spqr_tree:
|
3128
|
+
if t == 'R':
|
3129
|
+
R_frequency.update(g)
|
3130
|
+
|
3131
|
+
# R frequency must be at least 2,
|
3132
|
+
# since the graph is 2-connected but not 3-connected
|
3133
|
+
two_vertex_cut = [u for u, f in R_frequency.items() if f >= 2][:2]
|
3134
|
+
|
3135
|
+
# We obtain a 2-vertex cut (u, v)
|
3136
|
+
H = Graph(self)
|
3137
|
+
H.delete_vertices(two_vertex_cut)
|
3138
|
+
|
3139
|
+
# Check if all components of H are odd
|
3140
|
+
components = H.connected_components(sort=True)
|
3141
|
+
|
3142
|
+
# Find a nontrivial odd component
|
3143
|
+
nontrivial_tight_cut_variation = 'nontrivial 2-separation cut'
|
3144
|
+
nontrivial_odd_components = []
|
3145
|
+
|
3146
|
+
for index, component in enumerate(components):
|
3147
|
+
if index == len(components) - 1:
|
3148
|
+
continue
|
3149
|
+
elif not index:
|
3150
|
+
nontrivial_odd_components.append(set(components[0] + [two_vertex_cut[0]]))
|
3151
|
+
else:
|
3152
|
+
nontrivial_odd_component = nontrivial_odd_components[-1].copy()
|
3153
|
+
nontrivial_odd_component.update(component)
|
3154
|
+
nontrivial_odd_components.append(nontrivial_odd_component)
|
3155
|
+
|
3156
|
+
C = [[(u, v, w) if u in nontrivial_odd_component else (v, u, w)
|
3157
|
+
for u, v, w in self.edge_iterator()
|
3158
|
+
if (u in nontrivial_odd_component) ^ (v in nontrivial_odd_component)]
|
3159
|
+
for nontrivial_odd_component in nontrivial_odd_components]
|
3160
|
+
|
3161
|
+
# Edge (u, v, w) in C are formatted so that u is in a nontrivial odd component
|
3162
|
+
return (False, C, nontrivial_odd_components, nontrivial_tight_cut_variation, set(two_vertex_cut)) if coNP_certificate else False
|
3163
|
+
|
2351
3164
|
@doc_index('Overwritten methods')
|
2352
3165
|
def loop_edges(self, labels=True):
|
2353
3166
|
r"""
|
@@ -2418,13 +3231,13 @@ class MatchingCoveredGraph(Graph):
|
|
2418
3231
|
|
2419
3232
|
.. SEEALSO::
|
2420
3233
|
|
2421
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops
|
2422
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops
|
2423
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops
|
2424
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices
|
2425
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops
|
2426
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops
|
2427
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
3234
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`
|
3235
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`
|
3236
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`
|
3237
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`
|
3238
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`
|
3239
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`
|
3240
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
2428
3241
|
"""
|
2429
3242
|
return []
|
2430
3243
|
|
@@ -2485,13 +3298,13 @@ class MatchingCoveredGraph(Graph):
|
|
2485
3298
|
|
2486
3299
|
.. SEEALSO::
|
2487
3300
|
|
2488
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops
|
2489
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops
|
2490
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops
|
2491
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges
|
2492
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops
|
2493
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops
|
2494
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
3301
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`
|
3302
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`
|
3303
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`
|
3304
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`
|
3305
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`
|
3306
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`
|
3307
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
2495
3308
|
"""
|
2496
3309
|
return []
|
2497
3310
|
|
@@ -2557,13 +3370,13 @@ class MatchingCoveredGraph(Graph):
|
|
2557
3370
|
|
2558
3371
|
.. SEEALSO::
|
2559
3372
|
|
2560
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops
|
2561
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops
|
2562
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops
|
2563
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges
|
2564
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices
|
2565
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops
|
2566
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
3373
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`
|
3374
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`
|
3375
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`
|
3376
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`
|
3377
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`
|
3378
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`
|
3379
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops`
|
2567
3380
|
"""
|
2568
3381
|
return 0
|
2569
3382
|
|
@@ -2582,7 +3395,7 @@ class MatchingCoveredGraph(Graph):
|
|
2582
3395
|
INPUT:
|
2583
3396
|
|
2584
3397
|
- ``vertices`` -- (default: ``None``) iterator container of vertex
|
2585
|
-
labels
|
3398
|
+
labels corresponding to which the looped edges are to be removed. If
|
2586
3399
|
``vertices`` is ``None``, remove all loops.
|
2587
3400
|
|
2588
3401
|
OUTPUT:
|
@@ -2649,13 +3462,13 @@ class MatchingCoveredGraph(Graph):
|
|
2649
3462
|
|
2650
3463
|
.. SEEALSO::
|
2651
3464
|
|
2652
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops
|
2653
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops
|
2654
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops
|
2655
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges
|
2656
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices
|
2657
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops
|
2658
|
-
:meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`
|
3465
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`
|
3466
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`
|
3467
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`
|
3468
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`
|
3469
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`
|
3470
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`
|
3471
|
+
- :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`
|
2659
3472
|
"""
|
2660
3473
|
from collections.abc import Iterable
|
2661
3474
|
|
@@ -2663,8 +3476,6 @@ class MatchingCoveredGraph(Graph):
|
|
2663
3476
|
raise TypeError(f'\'{vertices.__class__.__name__}\' '
|
2664
3477
|
'object is not iterable')
|
2665
3478
|
|
2666
|
-
return
|
2667
|
-
|
2668
3479
|
@doc_index('Miscellaneous methods')
|
2669
3480
|
def update_matching(self, matching):
|
2670
3481
|
r"""
|
@@ -2752,4 +3563,4 @@ class MatchingCoveredGraph(Graph):
|
|
2752
3563
|
raise exception
|
2753
3564
|
|
2754
3565
|
|
2755
|
-
__doc__ = __doc__.replace('{INDEX_OF_METHODS}', gen_thematic_rest_table_index(MatchingCoveredGraph, only_local_functions=False))
|
3566
|
+
__doc__ = __doc__.replace('{INDEX_OF_METHODS}', gen_thematic_rest_table_index(MatchingCoveredGraph, only_local_functions=False))
|