Skip to content

Commit 59c81e8

Browse files
eumiroSILIZ4
authored andcommitted
Add docstring for some graph connectivity methods (Qiskit#1399)
1 parent b97aed3 commit 59c81e8

File tree

1 file changed

+145
-26
lines changed

1 file changed

+145
-26
lines changed

src/connectivity/mod.rs

Lines changed: 145 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,28 @@ pub fn simple_cycles(
100100
johnson_simple_cycles::PySimpleCycleIter::new(py, graph)
101101
}
102102

103-
/// Compute the strongly connected components for a directed graph
103+
/// Find the strongly connected components in a directed graph
104104
///
105-
/// This function is implemented using Kosaraju's algorithm
105+
/// A strongly connected component (SCC) is a maximal subset of vertices
106+
/// such that every vertex is reachable from every other vertex
107+
/// within that subset.
106108
///
107-
/// :param PyDiGraph graph: The input graph to find the strongly connected
108-
/// components for.
109+
/// This function is implemented using Kosaraju's algorithm.
109110
///
110-
/// :return: A list of list of node ids for strongly connected components
111-
/// :rtype: list
111+
/// >>> G = rx.PyDiGraph()
112+
/// >>> G.extend_from_edge_list([(0, 1), (1, 2), (2, 0), (3, 4)])
113+
/// >>> rx.strongly_connected_components(G)
114+
/// [[4], [3], [0, 1, 2]]
115+
///
116+
/// See also [weakly_connected_components].
117+
///
118+
/// For undirected graphs, see [connected_components].
119+
///
120+
/// :param PyDiGraph graph: The directed graph to find the strongly connected
121+
/// components in
122+
///
123+
/// :return: A list of lists of node indices of strongly connected components
124+
/// :rtype: list[list[int]]
112125
#[pyfunction]
113126
#[pyo3(text_signature = "(graph, /)")]
114127
pub fn strongly_connected_components(graph: &digraph::PyDiGraph) -> Vec<Vec<usize>> {
@@ -139,10 +152,26 @@ pub fn digraph_find_cycle(graph: &digraph::PyDiGraph, source: Option<usize>) ->
139152
}
140153
}
141154

142-
/// Find the number of connected components in an undirected graph.
155+
/// Find the number of connected components in an undirected graph
156+
///
157+
/// A connected component is a subset of the graph where there is a path
158+
/// between any two vertices in that subset, and which is connected
159+
/// to no additional vertices in the graph.
143160
///
144-
/// :param PyGraph graph: The graph to find the number of connected
145-
/// components on.
161+
/// >>> G = rx.PyGraph()
162+
/// >>> G.extend_from_edge_list([(0, 1), (1, 2), (3, 4)])
163+
/// >>> rx.number_connected_components(G)
164+
/// 2
165+
///
166+
/// To get these components, see [connected_components].
167+
///
168+
/// If ``rx.number_connected_components(G) == 1``,
169+
/// then ``rx.is_connected(G) is True``.
170+
///
171+
/// For directed graphs, see [number_weakly_connected_components].
172+
///
173+
/// :param PyGraph graph: The undirected graph to find the number of connected
174+
/// components in
146175
///
147176
/// :returns: The number of connected components in the graph
148177
/// :rtype: int
@@ -154,11 +183,24 @@ pub fn number_connected_components(graph: &graph::PyGraph) -> usize {
154183

155184
/// Find the connected components in an undirected graph
156185
///
157-
/// :param PyGraph graph: The graph to find the connected components.
186+
/// A connected component is a subset of an undirected graph where there is a path
187+
/// between any two vertices in that subset, and which is connected
188+
/// to no additional vertices in the graph.
189+
///
190+
/// >>> G = rx.PyGraph()
191+
/// >>> G.extend_from_edge_list([(0, 1), (1, 2), (3, 4)])
192+
/// >>> rx.connected_components(G)
193+
/// [{0, 1, 2}, {3, 4}]
158194
///
159-
/// :returns: A list of sets where each set is a connected component of
195+
/// To get just the number of these components, see [number_connected_components].
196+
///
197+
/// For directed graphs, see [weakly_connected_components] and [strongly_connected_components].
198+
///
199+
/// :param PyGraph graph: An undirected graph to find the connected components in
200+
///
201+
/// :returns: A list of sets of node indices where each set is a connected component of
160202
/// the graph
161-
/// :rtype: list
203+
/// :rtype: list[set[int]]
162204
#[pyfunction]
163205
#[pyo3(text_signature = "(graph, /)")]
164206
pub fn connected_components(graph: &graph::PyGraph) -> Vec<HashSet<usize>> {
@@ -196,9 +238,21 @@ pub fn node_connected_component(graph: &graph::PyGraph, node: usize) -> PyResult
196238
)
197239
}
198240

199-
/// Check if the graph is connected.
241+
/// Check if an undirected graph is fully connected
242+
///
243+
/// An undirected graph is considered connected if there is a path between
244+
/// every pair of vertices.
200245
///
201-
/// :param PyGraph graph: The graph to check if it is connected.
246+
/// >>> G = rx.PyGraph()
247+
/// >>> G.extend_from_edge_list([(0, 1), (1, 2), (3, 4)])
248+
/// >>> rx.is_connected(G)
249+
/// False
250+
///
251+
/// If ``rx.is_connected(G) is True`` then `rx.number_connected_components(G) == 1``.
252+
///
253+
/// For directed graphs see [is_weakly_connected].
254+
///
255+
/// :param PyGraph graph: An undirected graph to check for connectivity
202256
///
203257
/// :returns: Whether the graph is connected or not
204258
/// :rtype: bool
@@ -218,8 +272,26 @@ pub fn is_connected(graph: &graph::PyGraph) -> PyResult<bool> {
218272

219273
/// Find the number of weakly connected components in a directed graph
220274
///
221-
/// :param PyDiGraph graph: The graph to find the number of weakly connected
222-
/// components on
275+
/// A weakly connected component (WCC) is a maximal subset of vertices
276+
/// such that there is a path between any two vertices in the subset
277+
/// when the direction of edges is ignored.
278+
/// This means that if you treat the directed graph as an undirected graph,
279+
/// all vertices in a weakly connected component are reachable from one another.
280+
///
281+
/// >>> G = rx.PyDiGraph()
282+
/// >>> G.extend_from_edge_list([(0, 1), (1, 2), (3, 4)])
283+
/// >>> rx.number_weakly_connected_components(G)
284+
/// 2
285+
///
286+
/// To get these components, see [weakly_connected_components].
287+
///
288+
/// If ``rx.number_weakly_connected_components(G) == 1``,
289+
/// then ``rx.is_weakly_connected(G) is True``.
290+
///
291+
/// For undirected graphs, see [number_connected_components].
292+
///
293+
/// :param PyDiGraph graph: The directed graph to find the number
294+
/// of weakly connected components in
223295
///
224296
/// :returns: The number of weakly connected components in the graph
225297
/// :rtype: int
@@ -240,12 +312,28 @@ pub fn number_weakly_connected_components(graph: &digraph::PyDiGraph) -> usize {
240312

241313
/// Find the weakly connected components in a directed graph
242314
///
243-
/// :param PyDiGraph graph: The graph to find the weakly connected components
244-
/// in
315+
/// A weakly connected component (WCC) is a maximal subset of vertices
316+
/// such that there is a path between any two vertices in the subset
317+
/// when the direction of edges is ignored.
318+
/// This means that if you treat the directed graph as an undirected graph,
319+
/// all vertices in a weakly connected component are reachable from one another.
245320
///
246-
/// :returns: A list of sets where each set is a weakly connected component of
247-
/// the graph
248-
/// :rtype: list
321+
/// >>> G = rx.PyDiGraph()
322+
/// >>> G.extend_from_edge_list([(0, 1), (1, 2), (3, 4)])
323+
/// >>> rx.weakly_connected_components(G)
324+
/// [{0, 1, 2}, {3, 4}]
325+
///
326+
/// See also [strongly_connected_components].
327+
///
328+
/// To get just the number of these components, see [number_weakly_connected_components].
329+
///
330+
/// For undirected graphs, see [connected_components].
331+
///
332+
/// :param PyDiGraph graph: The directed graph to find the weakly connected
333+
/// components in.
334+
///
335+
/// :return: A list of sets of node indices of weakly connected components
336+
/// :rtype: list[set[int]]
249337
#[pyfunction]
250338
#[pyo3(text_signature = "(graph, /)")]
251339
pub fn weakly_connected_components(graph: &digraph::PyDiGraph) -> Vec<HashSet<usize>> {
@@ -255,11 +343,28 @@ pub fn weakly_connected_components(graph: &digraph::PyDiGraph) -> Vec<HashSet<us
255343
.collect()
256344
}
257345

258-
/// Check if the graph is weakly connected
346+
/// Check if a directed graph is weakly connected
259347
///
260-
/// :param PyDiGraph graph: The graph to check if it is weakly connected
348+
/// A directed graph is considered weakly connected
349+
/// if there is a path between every pair of vertices
350+
/// when the direction of edges is ignored.
351+
/// This means that if you treat the directed graph as an undirected graph,
352+
/// all vertices in a weakly connected graph are reachable from one another.
261353
///
262-
/// :returns: Whether the graph is weakly connected or not
354+
/// >>> G = rx.PyDiGraph()
355+
/// >>> G.extend_from_edge_list([(0, 1), (1, 2), (3, 4)])
356+
/// >>> rx.is_weakly_connected(G)
357+
/// False
358+
///
359+
/// See also [is_semi_connected].
360+
///
361+
/// If ``rx.is_weakly_connected(G) is True`` then `rx.number_weakly_connected_components(G) == 1``.
362+
///
363+
/// For undirected graphs see [is_connected].
364+
///
365+
/// :param PyGraph graph: An undirected graph to check for weak connectivity
366+
///
367+
/// :returns: Whether the graph is connected or not
263368
/// :rtype: bool
264369
///
265370
/// :raises NullGraph: If an empty graph is passed in
@@ -272,9 +377,23 @@ pub fn is_weakly_connected(graph: &digraph::PyDiGraph) -> PyResult<bool> {
272377
Ok(weakly_connected_components(graph)[0].len() == graph.graph.node_count())
273378
}
274379

275-
/// Check if the graph is semi connected
380+
/// Check if a directed graph is semi-connected
381+
///
382+
/// A directed graph is semi-connected if, for every pair of vertices `u` and `v`,
383+
/// there exists a directed path from `u` to `v` or from `v` to `u`,
384+
/// meaning that every vertex can reach every other vertex either
385+
/// directly or indirectly.
386+
///
387+
/// >>> G = rx.PyDiGraph()
388+
/// >>> G.extend_from_edge_list([(0, 1), (1, 2), (3, 4)])
389+
/// >>> rx.is_semi_connected(G)
390+
/// False
391+
///
392+
/// See also [is_weakly_connected].
393+
///
394+
/// For undirected graphs see [is_connected].
276395
///
277-
/// :param PyDiGraph graph: The graph to check if it is semi connected
396+
/// :param PyDiGraph graph: An undirected graph to check for semi-connectivity
278397
///
279398
/// :returns: Whether the graph is semi connected or not
280399
/// :rtype: bool

0 commit comments

Comments
 (0)