harary_graph.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. """Generators for Harary graphs
  2. This module gives two generators for the Harary graph, which was
  3. introduced by the famous mathematician Frank Harary in his 1962 work [H]_.
  4. The first generator gives the Harary graph that maximizes the node
  5. connectivity with given number of nodes and given number of edges.
  6. The second generator gives the Harary graph that minimizes
  7. the number of edges in the graph with given node connectivity and
  8. number of nodes.
  9. References
  10. ----------
  11. .. [H] Harary, F. "The Maximum Connectivity of a Graph."
  12. Proc. Nat. Acad. Sci. USA 48, 1142-1146, 1962.
  13. """
  14. import networkx as nx
  15. from networkx.exception import NetworkXError
  16. __all__ = ["hnm_harary_graph", "hkn_harary_graph"]
  17. @nx._dispatchable(graphs=None, returns_graph=True)
  18. def hnm_harary_graph(n, m, create_using=None):
  19. r"""Return the Harary graph with given numbers of nodes and edges.
  20. The Harary graph $H_{n, m}$ is the graph that maximizes node connectivity
  21. with $n$ nodes and $m$ edges.
  22. This maximum node connectivity is known to be $\lfloor 2m/n \rfloor$. [1]_
  23. Parameters
  24. ----------
  25. n: integer
  26. The number of nodes the generated graph is to contain.
  27. m: integer
  28. The number of edges the generated graph is to contain.
  29. create_using : NetworkX graph constructor, optional (default=nx.Graph)
  30. Graph type to create. If graph instance, then cleared before populated.
  31. Returns
  32. -------
  33. NetworkX graph
  34. The Harary graph $H_{n, m}$.
  35. See Also
  36. --------
  37. hkn_harary_graph
  38. Notes
  39. -----
  40. This algorithm runs in $O(m)$ time.
  41. The implementation follows [2]_.
  42. References
  43. ----------
  44. .. [1] F. T. Boesch, A. Satyanarayana, and C. L. Suffel,
  45. "A Survey of Some Network Reliability Analysis and Synthesis Results,"
  46. Networks, pp. 99-107, 2009.
  47. .. [2] Harary, F. "The Maximum Connectivity of a Graph."
  48. Proc. Nat. Acad. Sci. USA 48, 1142-1146, 1962.
  49. """
  50. if n < 1:
  51. raise NetworkXError("The number of nodes must be >= 1!")
  52. if m < n - 1:
  53. raise NetworkXError("The number of edges must be >= n - 1 !")
  54. if m > n * (n - 1) // 2:
  55. raise NetworkXError("The number of edges must be <= n(n-1)/2")
  56. # Get the floor of average node degree.
  57. d = 2 * m // n
  58. offset = d // 2
  59. H = nx.circulant_graph(n, range(1, offset + 1), create_using=create_using)
  60. half = n // 2
  61. if (n % 2 == 0) or (d % 2 == 0):
  62. # If d is odd; n must be even.
  63. if d % 2 == 1:
  64. # Add edges diagonally.
  65. H.add_edges_from((i, i + half) for i in range(half))
  66. r = 2 * m % n
  67. # Add remaining edges at offset + 1.
  68. H.add_edges_from((i, i + offset + 1) for i in range(r // 2))
  69. else:
  70. # Add the remaining m - n * offset edges between i and i + half.
  71. H.add_edges_from((i, (i + half) % n) for i in range(m - n * offset))
  72. return H
  73. @nx._dispatchable(graphs=None, returns_graph=True)
  74. def hkn_harary_graph(k, n, create_using=None):
  75. r"""Return the Harary graph with given node connectivity and node number.
  76. The Harary graph $H_{k, n}$ is the graph that minimizes the number of
  77. edges needed with given node connectivity $k$ and node number $n$.
  78. This smallest number of edges is known to be $\lceil kn/2 \rceil$ [1]_.
  79. Parameters
  80. ----------
  81. k: integer
  82. The node connectivity of the generated graph.
  83. n: integer
  84. The number of nodes the generated graph is to contain.
  85. create_using : NetworkX graph constructor, optional (default=nx.Graph)
  86. Graph type to create. If graph instance, then cleared before populated.
  87. Returns
  88. -------
  89. NetworkX graph
  90. The Harary graph $H_{k, n}$.
  91. See Also
  92. --------
  93. hnm_harary_graph
  94. Notes
  95. -----
  96. This algorithm runs in $O(kn)$ time.
  97. The implementation follows [2]_.
  98. References
  99. ----------
  100. .. [1] Weisstein, Eric W. "Harary Graph." From MathWorld--A Wolfram Web
  101. Resource. http://mathworld.wolfram.com/HararyGraph.html.
  102. .. [2] Harary, F. "The Maximum Connectivity of a Graph."
  103. Proc. Nat. Acad. Sci. USA 48, 1142-1146, 1962.
  104. """
  105. if k < 1:
  106. raise NetworkXError("The node connectivity must be >= 1!")
  107. if n < k + 1:
  108. raise NetworkXError("The number of nodes must be >= k+1 !")
  109. # In case of connectivity 1, simply return the path graph.
  110. if k == 1:
  111. return nx.path_graph(n, create_using)
  112. offset = k // 2
  113. H = nx.circulant_graph(n, range(1, offset + 1), create_using=create_using)
  114. half = n // 2
  115. if (k % 2 == 0) or (n % 2 == 0):
  116. # If k is odd; n must be even.
  117. if k % 2 == 1:
  118. # Add edges diagonally.
  119. H.add_edges_from((i, i + half) for i in range(half))
  120. else:
  121. # Add half + 1 edges between i and i + half.
  122. H.add_edges_from((i, (i + half) % n) for i in range(half + 1))
  123. return H