efficiency_measures.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. """Provides functions for computing the efficiency of nodes and graphs."""
  2. import networkx as nx
  3. from networkx.exception import NetworkXNoPath
  4. from ..utils import not_implemented_for
  5. __all__ = ["efficiency", "local_efficiency", "global_efficiency"]
  6. @not_implemented_for("directed")
  7. @nx._dispatchable
  8. def efficiency(G, u, v):
  9. """Returns the efficiency of a pair of nodes in a graph.
  10. The *efficiency* of a pair of nodes is the multiplicative inverse of the
  11. shortest path distance between the nodes [1]_. Returns 0 if no path
  12. between nodes.
  13. Parameters
  14. ----------
  15. G : :class:`networkx.Graph`
  16. An undirected graph for which to compute the average local efficiency.
  17. u, v : node
  18. Nodes in the graph ``G``.
  19. Returns
  20. -------
  21. float
  22. Multiplicative inverse of the shortest path distance between the nodes.
  23. Examples
  24. --------
  25. >>> G = nx.Graph([(0, 1), (0, 2), (0, 3), (1, 2), (1, 3)])
  26. >>> nx.efficiency(G, 2, 3) # this gives efficiency for node 2 and 3
  27. 0.5
  28. Notes
  29. -----
  30. Edge weights are ignored when computing the shortest path distances.
  31. See also
  32. --------
  33. local_efficiency
  34. global_efficiency
  35. References
  36. ----------
  37. .. [1] Latora, Vito, and Massimo Marchiori.
  38. "Efficient behavior of small-world networks."
  39. *Physical Review Letters* 87.19 (2001): 198701.
  40. <https://doi.org/10.1103/PhysRevLett.87.198701>
  41. """
  42. try:
  43. eff = 1 / nx.shortest_path_length(G, u, v)
  44. except NetworkXNoPath:
  45. eff = 0
  46. return eff
  47. @not_implemented_for("directed")
  48. @nx._dispatchable
  49. def global_efficiency(G):
  50. """Returns the average global efficiency of the graph.
  51. The *efficiency* of a pair of nodes in a graph is the multiplicative
  52. inverse of the shortest path distance between the nodes. The *average
  53. global efficiency* of a graph is the average efficiency of all pairs of
  54. nodes [1]_.
  55. Parameters
  56. ----------
  57. G : :class:`networkx.Graph`
  58. An undirected graph for which to compute the average global efficiency.
  59. Returns
  60. -------
  61. float
  62. The average global efficiency of the graph.
  63. Examples
  64. --------
  65. >>> G = nx.Graph([(0, 1), (0, 2), (0, 3), (1, 2), (1, 3)])
  66. >>> round(nx.global_efficiency(G), 12)
  67. 0.916666666667
  68. Notes
  69. -----
  70. Edge weights are ignored when computing the shortest path distances.
  71. See also
  72. --------
  73. local_efficiency
  74. References
  75. ----------
  76. .. [1] Latora, Vito, and Massimo Marchiori.
  77. "Efficient behavior of small-world networks."
  78. *Physical Review Letters* 87.19 (2001): 198701.
  79. <https://doi.org/10.1103/PhysRevLett.87.198701>
  80. """
  81. n = len(G)
  82. denom = n * (n - 1)
  83. if denom != 0:
  84. lengths = nx.all_pairs_shortest_path_length(G)
  85. g_eff = 0
  86. for source, targets in lengths:
  87. for target, distance in targets.items():
  88. if distance > 0:
  89. g_eff += 1 / distance
  90. g_eff /= denom
  91. # g_eff = sum(1 / d for s, tgts in lengths
  92. # for t, d in tgts.items() if d > 0) / denom
  93. else:
  94. g_eff = 0
  95. # TODO This can be made more efficient by computing all pairs shortest
  96. # path lengths in parallel.
  97. return g_eff
  98. @not_implemented_for("directed")
  99. @nx._dispatchable
  100. def local_efficiency(G):
  101. """Returns the average local efficiency of the graph.
  102. The *efficiency* of a pair of nodes in a graph is the multiplicative
  103. inverse of the shortest path distance between the nodes. The *local
  104. efficiency* of a node in the graph is the average global efficiency of the
  105. subgraph induced by the neighbors of the node. The *average local
  106. efficiency* is the average of the local efficiencies of each node [1]_.
  107. Parameters
  108. ----------
  109. G : :class:`networkx.Graph`
  110. An undirected graph for which to compute the average local efficiency.
  111. Returns
  112. -------
  113. float
  114. The average local efficiency of the graph.
  115. Examples
  116. --------
  117. >>> G = nx.Graph([(0, 1), (0, 2), (0, 3), (1, 2), (1, 3)])
  118. >>> nx.local_efficiency(G)
  119. 0.9166666666666667
  120. Notes
  121. -----
  122. Edge weights are ignored when computing the shortest path distances.
  123. See also
  124. --------
  125. global_efficiency
  126. References
  127. ----------
  128. .. [1] Latora, Vito, and Massimo Marchiori.
  129. "Efficient behavior of small-world networks."
  130. *Physical Review Letters* 87.19 (2001): 198701.
  131. <https://doi.org/10.1103/PhysRevLett.87.198701>
  132. """
  133. efficiency_list = (global_efficiency(G.subgraph(G[v])) for v in G)
  134. return sum(efficiency_list) / len(G)