current_flow_closeness.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. """Current-flow closeness centrality measures."""
  2. import networkx as nx
  3. from networkx.algorithms.centrality.flow_matrix import (
  4. CGInverseLaplacian,
  5. FullInverseLaplacian,
  6. SuperLUInverseLaplacian,
  7. )
  8. from networkx.utils import not_implemented_for, reverse_cuthill_mckee_ordering
  9. __all__ = ["current_flow_closeness_centrality", "information_centrality"]
  10. @not_implemented_for("directed")
  11. def current_flow_closeness_centrality(G, weight=None, dtype=float, solver="lu"):
  12. """Compute current-flow closeness centrality for nodes.
  13. Current-flow closeness centrality is variant of closeness
  14. centrality based on effective resistance between nodes in
  15. a network. This metric is also known as information centrality.
  16. Parameters
  17. ----------
  18. G : graph
  19. A NetworkX graph.
  20. weight : None or string, optional (default=None)
  21. If None, all edge weights are considered equal.
  22. Otherwise holds the name of the edge attribute used as weight.
  23. The weight reflects the capacity or the strength of the
  24. edge.
  25. dtype: data type (default=float)
  26. Default data type for internal matrices.
  27. Set to np.float32 for lower memory consumption.
  28. solver: string (default='lu')
  29. Type of linear solver to use for computing the flow matrix.
  30. Options are "full" (uses most memory), "lu" (recommended), and
  31. "cg" (uses least memory).
  32. Returns
  33. -------
  34. nodes : dictionary
  35. Dictionary of nodes with current flow closeness centrality as the value.
  36. See Also
  37. --------
  38. closeness_centrality
  39. Notes
  40. -----
  41. The algorithm is from Brandes [1]_.
  42. See also [2]_ for the original definition of information centrality.
  43. References
  44. ----------
  45. .. [1] Ulrik Brandes and Daniel Fleischer,
  46. Centrality Measures Based on Current Flow.
  47. Proc. 22nd Symp. Theoretical Aspects of Computer Science (STACS '05).
  48. LNCS 3404, pp. 533-544. Springer-Verlag, 2005.
  49. https://doi.org/10.1007/978-3-540-31856-9_44
  50. .. [2] Karen Stephenson and Marvin Zelen:
  51. Rethinking centrality: Methods and examples.
  52. Social Networks 11(1):1-37, 1989.
  53. https://doi.org/10.1016/0378-8733(89)90016-6
  54. """
  55. if not nx.is_connected(G):
  56. raise nx.NetworkXError("Graph not connected.")
  57. solvername = {
  58. "full": FullInverseLaplacian,
  59. "lu": SuperLUInverseLaplacian,
  60. "cg": CGInverseLaplacian,
  61. }
  62. n = G.number_of_nodes()
  63. ordering = list(reverse_cuthill_mckee_ordering(G))
  64. # make a copy with integer labels according to rcm ordering
  65. # this could be done without a copy if we really wanted to
  66. H = nx.relabel_nodes(G, dict(zip(ordering, range(n))))
  67. betweenness = dict.fromkeys(H, 0.0) # b[v]=0 for v in H
  68. n = H.number_of_nodes()
  69. L = nx.laplacian_matrix(H, nodelist=range(n), weight=weight).asformat("csc")
  70. L = L.astype(dtype)
  71. C2 = solvername[solver](L, width=1, dtype=dtype) # initialize solver
  72. for v in H:
  73. col = C2.get_row(v)
  74. for w in H:
  75. betweenness[v] += col[v] - 2 * col[w]
  76. betweenness[w] += col[v]
  77. for v in H:
  78. betweenness[v] = 1 / (betweenness[v])
  79. return {ordering[k]: v for k, v in betweenness.items()}
  80. information_centrality = current_flow_closeness_centrality