about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/networkx/algorithms/approximation/distance_measures.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/networkx/algorithms/approximation/distance_measures.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/networkx/algorithms/approximation/distance_measures.py')
-rw-r--r--.venv/lib/python3.12/site-packages/networkx/algorithms/approximation/distance_measures.py150
1 files changed, 150 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/networkx/algorithms/approximation/distance_measures.py b/.venv/lib/python3.12/site-packages/networkx/algorithms/approximation/distance_measures.py
new file mode 100644
index 00000000..d5847e65
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/networkx/algorithms/approximation/distance_measures.py
@@ -0,0 +1,150 @@
+"""Distance measures approximated metrics."""
+
+import networkx as nx
+from networkx.utils.decorators import py_random_state
+
+__all__ = ["diameter"]
+
+
+@py_random_state(1)
+@nx._dispatchable(name="approximate_diameter")
+def diameter(G, seed=None):
+    """Returns a lower bound on the diameter of the graph G.
+
+    The function computes a lower bound on the diameter (i.e., the maximum eccentricity)
+    of a directed or undirected graph G. The procedure used varies depending on the graph
+    being directed or not.
+
+    If G is an `undirected` graph, then the function uses the `2-sweep` algorithm [1]_.
+    The main idea is to pick the farthest node from a random node and return its eccentricity.
+
+    Otherwise, if G is a `directed` graph, the function uses the `2-dSweep` algorithm [2]_,
+    The procedure starts by selecting a random source node $s$ from which it performs a
+    forward and a backward BFS. Let $a_1$ and $a_2$ be the farthest nodes in the forward and
+    backward cases, respectively. Then, it computes the backward eccentricity of $a_1$ using
+    a backward BFS and the forward eccentricity of $a_2$ using a forward BFS.
+    Finally, it returns the best lower bound between the two.
+
+    In both cases, the time complexity is linear with respect to the size of G.
+
+    Parameters
+    ----------
+    G : NetworkX graph
+
+    seed : integer, random_state, or None (default)
+        Indicator of random number generation state.
+        See :ref:`Randomness<randomness>`.
+
+    Returns
+    -------
+    d : integer
+       Lower Bound on the Diameter of G
+
+    Examples
+    --------
+    >>> G = nx.path_graph(10)  # undirected graph
+    >>> nx.diameter(G)
+    9
+    >>> G = nx.cycle_graph(3, create_using=nx.DiGraph)  # directed graph
+    >>> nx.diameter(G)
+    2
+
+    Raises
+    ------
+    NetworkXError
+        If the graph is empty or
+        If the graph is undirected and not connected or
+        If the graph is directed and not strongly connected.
+
+    See Also
+    --------
+    networkx.algorithms.distance_measures.diameter
+
+    References
+    ----------
+    .. [1] Magnien, Clémence, Matthieu Latapy, and Michel Habib.
+       *Fast computation of empirically tight bounds for the diameter of massive graphs.*
+       Journal of Experimental Algorithmics (JEA), 2009.
+       https://arxiv.org/pdf/0904.2728.pdf
+    .. [2] Crescenzi, Pierluigi, Roberto Grossi, Leonardo Lanzi, and Andrea Marino.
+       *On computing the diameter of real-world directed (weighted) graphs.*
+       International Symposium on Experimental Algorithms. Springer, Berlin, Heidelberg, 2012.
+       https://courses.cs.ut.ee/MTAT.03.238/2014_fall/uploads/Main/diameter.pdf
+    """
+    # if G is empty
+    if not G:
+        raise nx.NetworkXError("Expected non-empty NetworkX graph!")
+    # if there's only a node
+    if G.number_of_nodes() == 1:
+        return 0
+    # if G is directed
+    if G.is_directed():
+        return _two_sweep_directed(G, seed)
+    # else if G is undirected
+    return _two_sweep_undirected(G, seed)
+
+
+def _two_sweep_undirected(G, seed):
+    """Helper function for finding a lower bound on the diameter
+        for undirected Graphs.
+
+        The idea is to pick the farthest node from a random node
+        and return its eccentricity.
+
+        ``G`` is a NetworkX undirected graph.
+
+    .. note::
+
+        ``seed`` is a random.Random or numpy.random.RandomState instance
+    """
+    # select a random source node
+    source = seed.choice(list(G))
+    # get the distances to the other nodes
+    distances = nx.shortest_path_length(G, source)
+    # if some nodes have not been visited, then the graph is not connected
+    if len(distances) != len(G):
+        raise nx.NetworkXError("Graph not connected.")
+    # take a node that is (one of) the farthest nodes from the source
+    *_, node = distances
+    # return the eccentricity of the node
+    return nx.eccentricity(G, node)
+
+
+def _two_sweep_directed(G, seed):
+    """Helper function for finding a lower bound on the diameter
+        for directed Graphs.
+
+        It implements 2-dSweep, the directed version of the 2-sweep algorithm.
+        The algorithm follows the following steps.
+        1. Select a source node $s$ at random.
+        2. Perform a forward BFS from $s$ to select a node $a_1$ at the maximum
+        distance from the source, and compute $LB_1$, the backward eccentricity of $a_1$.
+        3. Perform a backward BFS from $s$ to select a node $a_2$ at the maximum
+        distance from the source, and compute $LB_2$, the forward eccentricity of $a_2$.
+        4. Return the maximum between $LB_1$ and $LB_2$.
+
+        ``G`` is a NetworkX directed graph.
+
+    .. note::
+
+        ``seed`` is a random.Random or numpy.random.RandomState instance
+    """
+    # get a new digraph G' with the edges reversed in the opposite direction
+    G_reversed = G.reverse()
+    # select a random source node
+    source = seed.choice(list(G))
+    # compute forward distances from source
+    forward_distances = nx.shortest_path_length(G, source)
+    # compute backward distances  from source
+    backward_distances = nx.shortest_path_length(G_reversed, source)
+    # if either the source can't reach every node or not every node
+    # can reach the source, then the graph is not strongly connected
+    n = len(G)
+    if len(forward_distances) != n or len(backward_distances) != n:
+        raise nx.NetworkXError("DiGraph not strongly connected.")
+    # take a node a_1 at the maximum distance from the source in G
+    *_, a_1 = forward_distances
+    # take a node a_2 at the maximum distance from the source in G_reversed
+    *_, a_2 = backward_distances
+    # return the max between the backward eccentricity of a_1 and the forward eccentricity of a_2
+    return max(nx.eccentricity(G_reversed, a_1), nx.eccentricity(G, a_2))