centrality.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. import networkx as nx
  2. __all__ = ["degree_centrality", "betweenness_centrality", "closeness_centrality"]
  3. @nx._dispatchable(name="bipartite_degree_centrality")
  4. def degree_centrality(G, nodes):
  5. r"""Compute the degree centrality for nodes in a bipartite network.
  6. The degree centrality for a node `v` is the fraction of nodes
  7. connected to it.
  8. Parameters
  9. ----------
  10. G : graph
  11. A bipartite network
  12. nodes : list or container
  13. Container with all nodes in one bipartite node set.
  14. Returns
  15. -------
  16. centrality : dictionary
  17. Dictionary keyed by node with bipartite degree centrality as the value.
  18. Examples
  19. --------
  20. >>> G = nx.wheel_graph(5)
  21. >>> top_nodes = {0, 1, 2}
  22. >>> nx.bipartite.degree_centrality(G, nodes=top_nodes)
  23. {0: 2.0, 1: 1.5, 2: 1.5, 3: 1.0, 4: 1.0}
  24. See Also
  25. --------
  26. betweenness_centrality
  27. closeness_centrality
  28. :func:`~networkx.algorithms.bipartite.basic.sets`
  29. :func:`~networkx.algorithms.bipartite.basic.is_bipartite`
  30. Notes
  31. -----
  32. The nodes input parameter must contain all nodes in one bipartite node set,
  33. but the dictionary returned contains all nodes from both bipartite node
  34. sets. See :mod:`bipartite documentation <networkx.algorithms.bipartite>`
  35. for further details on how bipartite graphs are handled in NetworkX.
  36. For unipartite networks, the degree centrality values are
  37. normalized by dividing by the maximum possible degree (which is
  38. `n-1` where `n` is the number of nodes in G).
  39. In the bipartite case, the maximum possible degree of a node in a
  40. bipartite node set is the number of nodes in the opposite node set
  41. [1]_. The degree centrality for a node `v` in the bipartite
  42. sets `U` with `n` nodes and `V` with `m` nodes is
  43. .. math::
  44. d_{v} = \frac{deg(v)}{m}, \mbox{for} v \in U ,
  45. d_{v} = \frac{deg(v)}{n}, \mbox{for} v \in V ,
  46. where `deg(v)` is the degree of node `v`.
  47. References
  48. ----------
  49. .. [1] Borgatti, S.P. and Halgin, D. In press. "Analyzing Affiliation
  50. Networks". In Carrington, P. and Scott, J. (eds) The Sage Handbook
  51. of Social Network Analysis. Sage Publications.
  52. https://dx.doi.org/10.4135/9781446294413.n28
  53. """
  54. top = set(nodes)
  55. bottom = set(G) - top
  56. s = 1.0 / len(bottom)
  57. centrality = {n: d * s for n, d in G.degree(top)}
  58. s = 1.0 / len(top)
  59. centrality.update({n: d * s for n, d in G.degree(bottom)})
  60. return centrality
  61. @nx._dispatchable(name="bipartite_betweenness_centrality")
  62. def betweenness_centrality(G, nodes):
  63. r"""Compute betweenness centrality for nodes in a bipartite network.
  64. Betweenness centrality of a node `v` is the sum of the
  65. fraction of all-pairs shortest paths that pass through `v`.
  66. Values of betweenness are normalized by the maximum possible
  67. value which for bipartite graphs is limited by the relative size
  68. of the two node sets [1]_.
  69. Let `n` be the number of nodes in the node set `U` and
  70. `m` be the number of nodes in the node set `V`, then
  71. nodes in `U` are normalized by dividing by
  72. .. math::
  73. \frac{1}{2} [m^2 (s + 1)^2 + m (s + 1)(2t - s - 1) - t (2s - t + 3)] ,
  74. where
  75. .. math::
  76. s = (n - 1) \div m , t = (n - 1) \mod m ,
  77. and nodes in `V` are normalized by dividing by
  78. .. math::
  79. \frac{1}{2} [n^2 (p + 1)^2 + n (p + 1)(2r - p - 1) - r (2p - r + 3)] ,
  80. where,
  81. .. math::
  82. p = (m - 1) \div n , r = (m - 1) \mod n .
  83. Parameters
  84. ----------
  85. G : graph
  86. A bipartite graph
  87. nodes : list or container
  88. Container with all nodes in one bipartite node set.
  89. Returns
  90. -------
  91. betweenness : dictionary
  92. Dictionary keyed by node with bipartite betweenness centrality
  93. as the value.
  94. Examples
  95. --------
  96. >>> G = nx.cycle_graph(4)
  97. >>> top_nodes = {1, 2}
  98. >>> nx.bipartite.betweenness_centrality(G, nodes=top_nodes)
  99. {0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25}
  100. See Also
  101. --------
  102. degree_centrality
  103. closeness_centrality
  104. :func:`~networkx.algorithms.bipartite.basic.sets`
  105. :func:`~networkx.algorithms.bipartite.basic.is_bipartite`
  106. Notes
  107. -----
  108. The nodes input parameter must contain all nodes in one bipartite node set,
  109. but the dictionary returned contains all nodes from both node sets.
  110. See :mod:`bipartite documentation <networkx.algorithms.bipartite>`
  111. for further details on how bipartite graphs are handled in NetworkX.
  112. References
  113. ----------
  114. .. [1] Borgatti, S.P. and Halgin, D. In press. "Analyzing Affiliation
  115. Networks". In Carrington, P. and Scott, J. (eds) The Sage Handbook
  116. of Social Network Analysis. Sage Publications.
  117. https://dx.doi.org/10.4135/9781446294413.n28
  118. """
  119. top = set(nodes)
  120. bottom = set(G) - top
  121. n = len(top)
  122. m = len(bottom)
  123. s, t = divmod(n - 1, m)
  124. bet_max_top = (
  125. ((m**2) * ((s + 1) ** 2))
  126. + (m * (s + 1) * (2 * t - s - 1))
  127. - (t * ((2 * s) - t + 3))
  128. ) / 2.0
  129. p, r = divmod(m - 1, n)
  130. bet_max_bot = (
  131. ((n**2) * ((p + 1) ** 2))
  132. + (n * (p + 1) * (2 * r - p - 1))
  133. - (r * ((2 * p) - r + 3))
  134. ) / 2.0
  135. betweenness = nx.betweenness_centrality(G, normalized=False, weight=None)
  136. for node in top:
  137. betweenness[node] /= bet_max_top
  138. for node in bottom:
  139. betweenness[node] /= bet_max_bot
  140. return betweenness
  141. @nx._dispatchable(name="bipartite_closeness_centrality")
  142. def closeness_centrality(G, nodes, normalized=True):
  143. r"""Compute the closeness centrality for nodes in a bipartite network.
  144. The closeness of a node is the distance to all other nodes in the
  145. graph or in the case that the graph is not connected to all other nodes
  146. in the connected component containing that node.
  147. Parameters
  148. ----------
  149. G : graph
  150. A bipartite network
  151. nodes : list or container
  152. Container with all nodes in one bipartite node set.
  153. normalized : bool, optional
  154. If True (default) normalize by connected component size.
  155. Returns
  156. -------
  157. closeness : dictionary
  158. Dictionary keyed by node with bipartite closeness centrality
  159. as the value.
  160. Examples
  161. --------
  162. >>> G = nx.wheel_graph(5)
  163. >>> top_nodes = {0, 1, 2}
  164. >>> nx.bipartite.closeness_centrality(G, nodes=top_nodes)
  165. {0: 1.5, 1: 1.2, 2: 1.2, 3: 1.0, 4: 1.0}
  166. See Also
  167. --------
  168. betweenness_centrality
  169. degree_centrality
  170. :func:`~networkx.algorithms.bipartite.basic.sets`
  171. :func:`~networkx.algorithms.bipartite.basic.is_bipartite`
  172. Notes
  173. -----
  174. The nodes input parameter must contain all nodes in one bipartite node set,
  175. but the dictionary returned contains all nodes from both node sets.
  176. See :mod:`bipartite documentation <networkx.algorithms.bipartite>`
  177. for further details on how bipartite graphs are handled in NetworkX.
  178. Closeness centrality is normalized by the minimum distance possible.
  179. In the bipartite case the minimum distance for a node in one bipartite
  180. node set is 1 from all nodes in the other node set and 2 from all
  181. other nodes in its own set [1]_. Thus the closeness centrality
  182. for node `v` in the two bipartite sets `U` with
  183. `n` nodes and `V` with `m` nodes is
  184. .. math::
  185. c_{v} = \frac{m + 2(n - 1)}{d}, \mbox{for} v \in U,
  186. c_{v} = \frac{n + 2(m - 1)}{d}, \mbox{for} v \in V,
  187. where `d` is the sum of the distances from `v` to all
  188. other nodes.
  189. Higher values of closeness indicate higher centrality.
  190. As in the unipartite case, setting normalized=True causes the
  191. values to normalized further to n-1 / size(G)-1 where n is the
  192. number of nodes in the connected part of graph containing the
  193. node. If the graph is not completely connected, this algorithm
  194. computes the closeness centrality for each connected part
  195. separately.
  196. References
  197. ----------
  198. .. [1] Borgatti, S.P. and Halgin, D. In press. "Analyzing Affiliation
  199. Networks". In Carrington, P. and Scott, J. (eds) The Sage Handbook
  200. of Social Network Analysis. Sage Publications.
  201. https://dx.doi.org/10.4135/9781446294413.n28
  202. """
  203. closeness = {}
  204. path_length = nx.single_source_shortest_path_length
  205. top = set(nodes)
  206. bottom = set(G) - top
  207. n = len(top)
  208. m = len(bottom)
  209. for node in top:
  210. sp = dict(path_length(G, node))
  211. totsp = sum(sp.values())
  212. if totsp > 0.0 and len(G) > 1:
  213. closeness[node] = (m + 2 * (n - 1)) / totsp
  214. if normalized:
  215. s = (len(sp) - 1) / (len(G) - 1)
  216. closeness[node] *= s
  217. else:
  218. closeness[node] = 0.0
  219. for node in bottom:
  220. sp = dict(path_length(G, node))
  221. totsp = sum(sp.values())
  222. if totsp > 0.0 and len(G) > 1:
  223. closeness[node] = (n + 2 * (m - 1)) / totsp
  224. if normalized:
  225. s = (len(sp) - 1) / (len(G) - 1)
  226. closeness[node] *= s
  227. else:
  228. closeness[node] = 0.0
  229. return closeness