Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 152 additions & 8 deletions src/sage/graphs/connectivity.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ Here is what the module can do:
:meth:`connected_components_sizes` | Return the sizes of the connected components as a list.
:meth:`blocks_and_cut_vertices` | Return the blocks and cut vertices of the graph.
:meth:`blocks_and_cuts_tree` | Return the blocks-and-cuts tree of the graph.
:meth:`is_biconnected` | Check whether the graph is biconnected.
:meth:`biconnected_components` | Return the list of biconnected components.
:meth:`biconnected_components_subgraphs` | Return a list of biconnected components as graph objects.
:meth:`number_of_biconnected_components` | Return the number of biconnected components.
:meth:`is_cut_edge` | Check whether the input edge is a cut-edge or a bridge.
:meth:`is_edge_cut` | Check whether the input edges form an edge cut.
:meth:`is_cut_vertex` | Check whether the input vertex is a cut-vertex.
Expand Down Expand Up @@ -90,7 +93,7 @@ def is_connected(G, forbidden_vertices=None):

.. SEEALSO::

- :meth:`~Graph.is_biconnected`
- :meth:`~sage.graphs.generic_graph.GenericGraph.is_biconnected`

EXAMPLES::

Expand Down Expand Up @@ -505,7 +508,7 @@ def blocks_and_cut_vertices(G, algorithm='Tarjan_Boost', sort=False, key=None):

- :meth:`blocks_and_cuts_tree`
- :func:`sage.graphs.base.boost_graph.blocks_and_cut_vertices`
- :meth:`~Graph.is_biconnected`
- :meth:`~sage.graphs.generic_graph.GenericGraph.is_biconnected`
- :meth:`~Graph.bridges`

EXAMPLES:
Expand Down Expand Up @@ -716,7 +719,7 @@ def blocks_and_cuts_tree(G):
.. SEEALSO::

- :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices`
- :meth:`~Graph.is_biconnected`
- :meth:`~sage.graphs.generic_graph.GenericGraph.is_biconnected`

EXAMPLES::

Expand Down Expand Up @@ -778,12 +781,89 @@ def blocks_and_cuts_tree(G):
return g


def is_biconnected(G):
r"""
Check whether the graph is biconnected.

A biconnected graph is a connected graph on two or more vertices that is not
broken into disconnected pieces by deleting any single vertex.

.. SEEALSO::

- :meth:`~sage.graphs.generic_graph.GenericGraph.is_connected`
- :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices`
- :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cuts_tree`
- :wikipedia:`Biconnected_graph`

EXAMPLES::

sage: G = graphs.PetersenGraph()
sage: G.is_biconnected()
True
sage: G.add_path([0,'a','b'])
sage: G.is_biconnected()
False
sage: G.add_edge('b', 1)
sage: G.is_biconnected()
True

TESTS::

sage: Graph().is_biconnected()
False
sage: Graph(1).is_biconnected()
False
sage: graphs.CompleteGraph(2).is_biconnected()
True
"""
if G.order() < 2 or not G.is_connected():
return False
return not G.blocks_and_cut_vertices()[1]


def biconnected_components(G):
r"""
Return the list of biconnected components.

A biconnected component is a maximal subgraph on two or more vertices that
is biconnected, i.e., removing any vertex does not disconnect it.

INPUT:

- ``G`` -- the input graph

EXAMPLES::

sage: from sage.graphs.connectivity import biconnected_components
sage: G = Graph({0: [1, 2], 1: [0, 2], 2: [0, 1, 3], 3: [2]})
sage: sorted(len(b) for b in biconnected_components(G))
[2, 3]
sage: sorted(len(b) for b in biconnected_components(2 * G))
[2, 2, 3, 3]

TESTS:

If ``G`` is not a Sage graph, an error is raised::

sage: from sage.graphs.connectivity import biconnected_components
sage: biconnected_components('I am not a graph')
Traceback (most recent call last):
...
TypeError: the input must be a Sage graph
"""
from sage.graphs.generic_graph import GenericGraph
if not isinstance(G, GenericGraph):
raise TypeError("the input must be a Sage graph")

return [b for b in blocks_and_cut_vertices(G)[0] if len(b) > 1]


def biconnected_components_subgraphs(G):
r"""
Return a list of biconnected components as graph objects.

A biconnected component is a maximal subgraph that is biconnected, i.e.,
removing any vertex does not disconnect it.
A biconnected component is a maximal subgraph on two or more vertices that
is biconnected, i.e., removing any vertex does not disconnect it.

INPUT:

Expand Down Expand Up @@ -815,7 +895,71 @@ def biconnected_components_subgraphs(G):
if not isinstance(G, GenericGraph):
raise TypeError("the input must be a Sage graph")

return [G.subgraph(c) for c in blocks_and_cut_vertices(G)[0]]
return [G.subgraph(c) for c in G.biconnected_components()]


def number_of_biconnected_components(G):
r"""
Return the number of biconnected components.

A biconnected component is a maximal subgraph on two or more vertices that
is biconnected, i.e., removing any vertex does not disconnect it.

.. SEEALSO::

- :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices`
- :meth:`~sage.graphs.generic_graph.GenericGraph.is_biconnected`

EXAMPLES:

The disjoint union of cycles has as many biconnected components as the
number of cycles::

sage: G = graphs.CycleGraph(5)
sage: G.number_of_biconnected_components()
1
sage: (3 * G).number_of_biconnected_components()
3

A block graph is a connected graph in which every biconnected component
(block) is a clique. Hence its number of biconnected components is its
number of blocks::

sage: number_of_blocks = randint(4, 10)
sage: G = graphs.RandomBlockGraph(number_of_blocks, 5)
sage: G.number_of_biconnected_components() == number_of_blocks
True

By definition, an edge is a biconnected component. Hence, the number of
biconnected components of a tree is its number of edges::

sage: T = graphs.RandomTree(randint(0, 10))
sage: T.number_of_biconnected_components() == T.size()
True

An isolated vertex is a block but not a biconnected component::

sage: G = Graph(3)
sage: len(G.blocks_and_cut_vertices()[0])
3
sage: G.number_of_biconnected_components()
0

TESTS:

An error is raised if the input is not a Sage graph::

sage: from sage.graphs.connectivity import number_of_biconnected_components
sage: number_of_biconnected_components('I am not a graph')
Traceback (most recent call last):
...
TypeError: the input must be a Sage graph
"""
from sage.graphs.generic_graph import GenericGraph
if not isinstance(G, GenericGraph):
raise TypeError("the input must be a Sage graph")

return len(G.biconnected_components())


def is_edge_cut(G, edges):
Expand Down Expand Up @@ -3363,7 +3507,7 @@ cdef class TriconnectivitySPQR:
.. SEEALSO::

- :meth:`sage.graphs.connectivity.spqr_tree`
- :meth:`~Graph.is_biconnected`
- :meth:`~sage.graphs.generic_graph.GenericGraph.is_biconnected`
- :wikipedia:`SPQR_tree`

EXAMPLES:
Expand Down Expand Up @@ -4789,7 +4933,7 @@ def is_triconnected(G):
.. SEEALSO::

- :meth:`~sage.graphs.generic_graph.GenericGraph.is_connected`
- :meth:`~Graph.is_biconnected`
- :meth:`~sage.graphs.generic_graph.GenericGraph.is_biconnected`
- :meth:`~sage.graphs.connectivity.spqr_tree`
- :wikipedia:`SPQR_tree`

Expand Down
8 changes: 7 additions & 1 deletion src/sage/graphs/generic_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,18 @@
:widths: 30, 70
:delim: |

:meth:`~GenericGraph.is_connected` | Test whether the (di)graph is connected.
:meth:`~GenericGraph.is_connected` | Check whether the (di)graph is connected.
:meth:`~GenericGraph.connected_components` | Return the list of connected components
:meth:`~GenericGraph.connected_components_number` | Return the number of connected components.
:meth:`~GenericGraph.connected_components_subgraphs` | Return a list of connected components as graph objects.
:meth:`~GenericGraph.connected_component_containing_vertex` | Return a list of the vertices connected to vertex.
:meth:`~GenericGraph.connected_components_sizes` | Return the sizes of the connected components as a list.
:meth:`~GenericGraph.blocks_and_cut_vertices` | Compute the blocks and cut vertices of the graph.
:meth:`~GenericGraph.blocks_and_cuts_tree` | Compute the blocks-and-cuts tree of the graph.
:meth:`~GenericGraph.is_biconnected` | Check whether the graph is biconnected.
:meth:`~GenericGraph.biconnected_components` | Return the list of biconnected components.
:meth:`~GenericGraph.biconnected_components_subgraphs` | Return a list of biconnected components as graph objects.
:meth:`~GenericGraph.number_of_biconnected_components` | Return the number of biconnected components.
:meth:`~GenericGraph.is_cut_edge` | Check whether the input edge is a cut-edge or a bridge.
:meth:`~GenericGraph.is_edge_cut` | Check whether the input edges form an edge cut.
:meth:`~GenericGraph.is_cut_vertex` | Check whether the input vertex is a cut-vertex.
Expand Down Expand Up @@ -25991,6 +25994,7 @@ def is_self_complementary(self):
from sage.graphs.base.static_dense_graph import connected_subgraph_iterator
from sage.graphs.base.static_sparse_graph import spectral_radius
from sage.graphs.connectivity import (
biconnected_components,
biconnected_components_subgraphs,
blocks_and_cut_vertices,
blocks_and_cuts_tree,
Expand All @@ -26000,11 +26004,13 @@ def is_self_complementary(self):
connected_components_sizes,
connected_components_subgraphs,
edge_connectivity,
is_biconnected,
is_connected,
is_cut_edge,
is_cut_vertex,
is_edge_cut,
is_vertex_cut,
number_of_biconnected_components,
vertex_connectivity,
)
from sage.graphs.distances_all_pairs import distances_distribution, szeged_index
Expand Down
40 changes: 0 additions & 40 deletions src/sage/graphs/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -1754,46 +1754,6 @@
B = self.blocks_and_cut_vertices()[0]
return len(self.faces()) == sum(1 for b in B if len(b) > 2) + 1

@doc_index("Graph properties")
def is_biconnected(self):
"""
Test if the graph is biconnected.

A biconnected graph is a connected graph on two or more vertices that is
not broken into disconnected pieces by deleting any single vertex.

.. SEEALSO::

- :meth:`~sage.graphs.generic_graph.GenericGraph.is_connected`
- :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices`
- :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cuts_tree`
- :wikipedia:`Biconnected_graph`

EXAMPLES::

sage: G = graphs.PetersenGraph()
sage: G.is_biconnected()
True
sage: G.add_path([0,'a','b'])
sage: G.is_biconnected()
False
sage: G.add_edge('b', 1)
sage: G.is_biconnected()
True

TESTS::

sage: Graph().is_biconnected()
False
sage: Graph(1).is_biconnected()
False
sage: graphs.CompleteGraph(2).is_biconnected()
True
"""
if self.order() < 2 or not self.is_connected():
return False
return not self.blocks_and_cut_vertices()[1]

@doc_index("Graph properties")
def is_block_graph(self):
r"""
Expand Down Expand Up @@ -9568,7 +9528,7 @@
The Peterson graph is a known projective planar graph::

sage: P = graphs.PetersenGraph()
sage: P.is_projective_planar() # long time

Check warning on line 9531 in src/sage/graphs/graph.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.12, new)

Warning: slow doctest:

slow doctest:: Test ran for 245.03s cpu, 245.12s wall Check ran for 0.00s cpu, 0.00s wall

Check warning on line 9531 in src/sage/graphs/graph.py

View workflow job for this annotation

GitHub Actions / test-long (src/sage/[g-o]*)

Warning: slow doctest:

slow doctest:: Test ran for 357.98s cpu, 360.55s wall Check ran for 0.00s cpu, 0.00s wall
True

`K_{4,4}` has a projective plane crossing number of 2. One of the
Expand Down
2 changes: 1 addition & 1 deletion src/sage/graphs/isgci.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@

* - Biconnected

- :meth:`~sage.graphs.graph.Graph.is_biconnected`,
- :meth:`~sage.graphs.generic_graph.GenericGraph.is_biconnected`,
:meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices`,
:meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cuts_tree`

Expand Down
4 changes: 2 additions & 2 deletions src/sage/graphs/matching_covered_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -2387,8 +2387,8 @@ def is_biconnected(self):
.. NOTE::

This method overwrites the
:meth:`~sage.graphs.graph.Graph.is_biconnected` method
in order to return ``True`` as matching covered graphs are
:meth:`~sage.graphs.generic_graph.GenericGraph.is_biconnected`
method in order to return ``True`` as matching covered graphs are
biconnected.

EXAMPLES:
Expand Down
Loading