efficiency_measures.py 4.6 KB

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