Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/networkx/algorithms/centrality/voterank_alg.py: 12%
33 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"""Algorithm to select influential nodes in a graph using VoteRank."""
2import networkx as nx
4__all__ = ["voterank"]
7@nx._dispatch
8def voterank(G, number_of_nodes=None):
9 """Select a list of influential nodes in a graph using VoteRank algorithm
11 VoteRank [1]_ computes a ranking of the nodes in a graph G based on a
12 voting scheme. With VoteRank, all nodes vote for each of its in-neighbours
13 and the node with the highest votes is elected iteratively. The voting
14 ability of out-neighbors of elected nodes is decreased in subsequent turns.
16 Parameters
17 ----------
18 G : graph
19 A NetworkX graph.
21 number_of_nodes : integer, optional
22 Number of ranked nodes to extract (default all nodes).
24 Returns
25 -------
26 voterank : list
27 Ordered list of computed seeds.
28 Only nodes with positive number of votes are returned.
30 Examples
31 --------
32 >>> G = nx.Graph([(0, 1), (0, 2), (0, 3), (1, 4)])
33 >>> nx.voterank(G)
34 [0, 1]
36 The algorithm can be used both for undirected and directed graphs.
37 However, the directed version is different in two ways:
38 (i) nodes only vote for their in-neighbors and
39 (ii) only the voting ability of elected node and its out-neighbors are updated:
41 >>> G = nx.DiGraph([(0, 1), (2, 1), (2, 3), (3, 4)])
42 >>> nx.voterank(G)
43 [2, 3]
45 Notes
46 -----
47 Each edge is treated independently in case of multigraphs.
49 References
50 ----------
51 .. [1] Zhang, J.-X. et al. (2016).
52 Identifying a set of influential spreaders in complex networks.
53 Sci. Rep. 6, 27823; doi: 10.1038/srep27823.
54 """
55 influential_nodes = []
56 vote_rank = {}
57 if len(G) == 0:
58 return influential_nodes
59 if number_of_nodes is None or number_of_nodes > len(G):
60 number_of_nodes = len(G)
61 if G.is_directed():
62 # For directed graphs compute average out-degree
63 avgDegree = sum(deg for _, deg in G.out_degree()) / len(G)
64 else:
65 # For undirected graphs compute average degree
66 avgDegree = sum(deg for _, deg in G.degree()) / len(G)
67 # step 1 - initiate all nodes to (0,1) (score, voting ability)
68 for n in G.nodes():
69 vote_rank[n] = [0, 1]
70 # Repeat steps 1b to 4 until num_seeds are elected.
71 for _ in range(number_of_nodes):
72 # step 1b - reset rank
73 for n in G.nodes():
74 vote_rank[n][0] = 0
75 # step 2 - vote
76 for n, nbr in G.edges():
77 # In directed graphs nodes only vote for their in-neighbors
78 vote_rank[n][0] += vote_rank[nbr][1]
79 if not G.is_directed():
80 vote_rank[nbr][0] += vote_rank[n][1]
81 for n in influential_nodes:
82 vote_rank[n][0] = 0
83 # step 3 - select top node
84 n = max(G.nodes, key=lambda x: vote_rank[x][0])
85 if vote_rank[n][0] == 0:
86 return influential_nodes
87 influential_nodes.append(n)
88 # weaken the selected node
89 vote_rank[n] = [0, 0]
90 # step 4 - update voterank properties
91 for _, nbr in G.edges(n):
92 vote_rank[nbr][1] -= 1 / avgDegree
93 vote_rank[nbr][1] = max(vote_rank[nbr][1], 0)
94 return influential_nodes