Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/networkx/generators/duplication.py: 22%
46 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-20 07:00 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-20 07:00 +0000
1"""Functions for generating graphs based on the "duplication" method.
3These graph generators start with a small initial graph then duplicate
4nodes and (partially) duplicate their edges. These functions are
5generally inspired by biological networks.
7"""
8import networkx as nx
9from networkx.exception import NetworkXError
10from networkx.utils import py_random_state
12__all__ = ["partial_duplication_graph", "duplication_divergence_graph"]
15@py_random_state(4)
16@nx._dispatch(graphs=None)
17def partial_duplication_graph(N, n, p, q, seed=None):
18 """Returns a random graph using the partial duplication model.
20 Parameters
21 ----------
22 N : int
23 The total number of nodes in the final graph.
25 n : int
26 The number of nodes in the initial clique.
28 p : float
29 The probability of joining each neighbor of a node to the
30 duplicate node. Must be a number in the between zero and one,
31 inclusive.
33 q : float
34 The probability of joining the source node to the duplicate
35 node. Must be a number in the between zero and one, inclusive.
37 seed : integer, random_state, or None (default)
38 Indicator of random number generation state.
39 See :ref:`Randomness<randomness>`.
41 Notes
42 -----
43 A graph of nodes is grown by creating a fully connected graph
44 of size `n`. The following procedure is then repeated until
45 a total of `N` nodes have been reached.
47 1. A random node, *u*, is picked and a new node, *v*, is created.
48 2. For each neighbor of *u* an edge from the neighbor to *v* is created
49 with probability `p`.
50 3. An edge from *u* to *v* is created with probability `q`.
52 This algorithm appears in [1].
54 This implementation allows the possibility of generating
55 disconnected graphs.
57 References
58 ----------
59 .. [1] Knudsen Michael, and Carsten Wiuf. "A Markov chain approach to
60 randomly grown graphs." Journal of Applied Mathematics 2008.
61 <https://doi.org/10.1155/2008/190836>
63 """
64 if p < 0 or p > 1 or q < 0 or q > 1:
65 msg = "partial duplication graph must have 0 <= p, q <= 1."
66 raise NetworkXError(msg)
67 if n > N:
68 raise NetworkXError("partial duplication graph must have n <= N.")
70 G = nx.complete_graph(n)
71 for new_node in range(n, N):
72 # Pick a random vertex, u, already in the graph.
73 src_node = seed.randint(0, new_node - 1)
75 # Add a new vertex, v, to the graph.
76 G.add_node(new_node)
78 # For each neighbor of u...
79 for neighbor_node in list(nx.all_neighbors(G, src_node)):
80 # Add the neighbor to v with probability p.
81 if seed.random() < p:
82 G.add_edge(new_node, neighbor_node)
84 # Join v and u with probability q.
85 if seed.random() < q:
86 G.add_edge(new_node, src_node)
87 return G
90@py_random_state(2)
91@nx._dispatch(graphs=None)
92def duplication_divergence_graph(n, p, seed=None):
93 """Returns an undirected graph using the duplication-divergence model.
95 A graph of `n` nodes is created by duplicating the initial nodes
96 and retaining edges incident to the original nodes with a retention
97 probability `p`.
99 Parameters
100 ----------
101 n : int
102 The desired number of nodes in the graph.
103 p : float
104 The probability for retaining the edge of the replicated node.
105 seed : integer, random_state, or None (default)
106 Indicator of random number generation state.
107 See :ref:`Randomness<randomness>`.
109 Returns
110 -------
111 G : Graph
113 Raises
114 ------
115 NetworkXError
116 If `p` is not a valid probability.
117 If `n` is less than 2.
119 Notes
120 -----
121 This algorithm appears in [1].
123 This implementation disallows the possibility of generating
124 disconnected graphs.
126 References
127 ----------
128 .. [1] I. Ispolatov, P. L. Krapivsky, A. Yuryev,
129 "Duplication-divergence model of protein interaction network",
130 Phys. Rev. E, 71, 061911, 2005.
132 """
133 if p > 1 or p < 0:
134 msg = f"NetworkXError p={p} is not in [0,1]."
135 raise nx.NetworkXError(msg)
136 if n < 2:
137 msg = "n must be greater than or equal to 2"
138 raise nx.NetworkXError(msg)
140 G = nx.Graph()
142 # Initialize the graph with two connected nodes.
143 G.add_edge(0, 1)
144 i = 2
145 while i < n:
146 # Choose a random node from current graph to duplicate.
147 random_node = seed.choice(list(G))
148 # Make the replica.
149 G.add_node(i)
150 # flag indicates whether at least one edge is connected on the replica.
151 flag = False
152 for nbr in G.neighbors(random_node):
153 if seed.random() < p:
154 # Link retention step.
155 G.add_edge(i, nbr)
156 flag = True
157 if not flag:
158 # Delete replica if no edges retained.
159 G.remove_node(i)
160 else:
161 # Successful duplication.
162 i += 1
163 return G