about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/networkx/generators/duplication.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/generators/duplication.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-4a52a71956a8d46fcb7294ac71734504bb09bcc2.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/networkx/generators/duplication.py')
-rw-r--r--.venv/lib/python3.12/site-packages/networkx/generators/duplication.py174
1 files changed, 174 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/networkx/generators/duplication.py b/.venv/lib/python3.12/site-packages/networkx/generators/duplication.py
new file mode 100644
index 00000000..3c3ade63
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/networkx/generators/duplication.py
@@ -0,0 +1,174 @@
+"""Functions for generating graphs based on the "duplication" method.
+
+These graph generators start with a small initial graph then duplicate
+nodes and (partially) duplicate their edges. These functions are
+generally inspired by biological networks.
+
+"""
+
+import networkx as nx
+from networkx.exception import NetworkXError
+from networkx.utils import py_random_state
+from networkx.utils.misc import check_create_using
+
+__all__ = ["partial_duplication_graph", "duplication_divergence_graph"]
+
+
+@py_random_state(4)
+@nx._dispatchable(graphs=None, returns_graph=True)
+def partial_duplication_graph(N, n, p, q, seed=None, *, create_using=None):
+    """Returns a random graph using the partial duplication model.
+
+    Parameters
+    ----------
+    N : int
+        The total number of nodes in the final graph.
+
+    n : int
+        The number of nodes in the initial clique.
+
+    p : float
+        The probability of joining each neighbor of a node to the
+        duplicate node. Must be a number in the between zero and one,
+        inclusive.
+
+    q : float
+        The probability of joining the source node to the duplicate
+        node. Must be a number in the between zero and one, inclusive.
+
+    seed : integer, random_state, or None (default)
+        Indicator of random number generation state.
+        See :ref:`Randomness<randomness>`.
+
+    create_using : Graph constructor, optional (default=nx.Graph)
+        Graph type to create. If graph instance, then cleared before populated.
+        Multigraph and directed types are not supported and raise a ``NetworkXError``.
+
+    Notes
+    -----
+    A graph of nodes is grown by creating a fully connected graph
+    of size `n`. The following procedure is then repeated until
+    a total of `N` nodes have been reached.
+
+    1. A random node, *u*, is picked and a new node, *v*, is created.
+    2. For each neighbor of *u* an edge from the neighbor to *v* is created
+       with probability `p`.
+    3. An edge from *u* to *v* is created with probability `q`.
+
+    This algorithm appears in [1].
+
+    This implementation allows the possibility of generating
+    disconnected graphs.
+
+    References
+    ----------
+    .. [1] Knudsen Michael, and Carsten Wiuf. "A Markov chain approach to
+           randomly grown graphs." Journal of Applied Mathematics 2008.
+           <https://doi.org/10.1155/2008/190836>
+
+    """
+    create_using = check_create_using(create_using, directed=False, multigraph=False)
+    if p < 0 or p > 1 or q < 0 or q > 1:
+        msg = "partial duplication graph must have 0 <= p, q <= 1."
+        raise NetworkXError(msg)
+    if n > N:
+        raise NetworkXError("partial duplication graph must have n <= N.")
+
+    G = nx.complete_graph(n, create_using)
+    for new_node in range(n, N):
+        # Pick a random vertex, u, already in the graph.
+        src_node = seed.randint(0, new_node - 1)
+
+        # Add a new vertex, v, to the graph.
+        G.add_node(new_node)
+
+        # For each neighbor of u...
+        for nbr_node in list(nx.all_neighbors(G, src_node)):
+            # Add the neighbor to v with probability p.
+            if seed.random() < p:
+                G.add_edge(new_node, nbr_node)
+
+        # Join v and u with probability q.
+        if seed.random() < q:
+            G.add_edge(new_node, src_node)
+    return G
+
+
+@py_random_state(2)
+@nx._dispatchable(graphs=None, returns_graph=True)
+def duplication_divergence_graph(n, p, seed=None, *, create_using=None):
+    """Returns an undirected graph using the duplication-divergence model.
+
+    A graph of `n` nodes is created by duplicating the initial nodes
+    and retaining edges incident to the original nodes with a retention
+    probability `p`.
+
+    Parameters
+    ----------
+    n : int
+        The desired number of nodes in the graph.
+    p : float
+        The probability for retaining the edge of the replicated node.
+    seed : integer, random_state, or None (default)
+        Indicator of random number generation state.
+        See :ref:`Randomness<randomness>`.
+    create_using : Graph constructor, optional (default=nx.Graph)
+        Graph type to create. If graph instance, then cleared before populated.
+        Multigraph and directed types are not supported and raise a ``NetworkXError``.
+
+    Returns
+    -------
+    G : Graph
+
+    Raises
+    ------
+    NetworkXError
+        If `p` is not a valid probability.
+        If `n` is less than 2.
+
+    Notes
+    -----
+    This algorithm appears in [1].
+
+    This implementation disallows the possibility of generating
+    disconnected graphs.
+
+    References
+    ----------
+    .. [1] I. Ispolatov, P. L. Krapivsky, A. Yuryev,
+       "Duplication-divergence model of protein interaction network",
+       Phys. Rev. E, 71, 061911, 2005.
+
+    """
+    if p > 1 or p < 0:
+        msg = f"NetworkXError p={p} is not in [0,1]."
+        raise nx.NetworkXError(msg)
+    if n < 2:
+        msg = "n must be greater than or equal to 2"
+        raise nx.NetworkXError(msg)
+
+    create_using = check_create_using(create_using, directed=False, multigraph=False)
+    G = nx.empty_graph(create_using=create_using)
+
+    # Initialize the graph with two connected nodes.
+    G.add_edge(0, 1)
+    i = 2
+    while i < n:
+        # Choose a random node from current graph to duplicate.
+        random_node = seed.choice(list(G))
+        # Make the replica.
+        G.add_node(i)
+        # flag indicates whether at least one edge is connected on the replica.
+        flag = False
+        for nbr in G.neighbors(random_node):
+            if seed.random() < p:
+                # Link retention step.
+                G.add_edge(i, nbr)
+                flag = True
+        if not flag:
+            # Delete replica if no edges retained.
+            G.remove_node(i)
+        else:
+            # Successful duplication.
+            i += 1
+    return G