123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- """Generators for Harary graphs
- This module gives two generators for the Harary graph, which was
- introduced by the famous mathematician Frank Harary in his 1962 work [H]_.
- The first generator gives the Harary graph that maximizes the node
- connectivity with given number of nodes and given number of edges.
- The second generator gives the Harary graph that minimizes
- the number of edges in the graph with given node connectivity and
- number of nodes.
- References
- ----------
- .. [H] Harary, F. "The Maximum Connectivity of a Graph."
- Proc. Nat. Acad. Sci. USA 48, 1142-1146, 1962.
- """
- import networkx as nx
- from networkx.exception import NetworkXError
- __all__ = ["hnm_harary_graph", "hkn_harary_graph"]
- def hnm_harary_graph(n, m, create_using=None):
- """Returns the Harary graph with given numbers of nodes and edges.
- The Harary graph $H_{n,m}$ is the graph that maximizes node connectivity
- with $n$ nodes and $m$ edges.
- This maximum node connectivity is known to be floor($2m/n$). [1]_
- Parameters
- ----------
- n: integer
- The number of nodes the generated graph is to contain
- m: integer
- The number of edges the generated graph is to contain
- create_using : NetworkX graph constructor, optional Graph type
- to create (default=nx.Graph). If graph instance, then cleared
- before populated.
- Returns
- -------
- NetworkX graph
- The Harary graph $H_{n,m}$.
- See Also
- --------
- hkn_harary_graph
- Notes
- -----
- This algorithm runs in $O(m)$ time.
- It is implemented by following the Reference [2]_.
- References
- ----------
- .. [1] F. T. Boesch, A. Satyanarayana, and C. L. Suffel,
- "A Survey of Some Network Reliability Analysis and Synthesis Results,"
- Networks, pp. 99-107, 2009.
- .. [2] Harary, F. "The Maximum Connectivity of a Graph."
- Proc. Nat. Acad. Sci. USA 48, 1142-1146, 1962.
- """
- if n < 1:
- raise NetworkXError("The number of nodes must be >= 1!")
- if m < n - 1:
- raise NetworkXError("The number of edges must be >= n - 1 !")
- if m > n * (n - 1) // 2:
- raise NetworkXError("The number of edges must be <= n(n-1)/2")
- # Construct an empty graph with n nodes first
- H = nx.empty_graph(n, create_using)
- # Get the floor of average node degree
- d = 2 * m // n
- # Test the parity of n and d
- if (n % 2 == 0) or (d % 2 == 0):
- # Start with a regular graph of d degrees
- offset = d // 2
- for i in range(n):
- for j in range(1, offset + 1):
- H.add_edge(i, (i - j) % n)
- H.add_edge(i, (i + j) % n)
- if d & 1:
- # in case d is odd; n must be even in this case
- half = n // 2
- for i in range(0, half):
- # add edges diagonally
- H.add_edge(i, i + half)
- # Get the remainder of 2*m modulo n
- r = 2 * m % n
- if r > 0:
- # add remaining edges at offset+1
- for i in range(0, r // 2):
- H.add_edge(i, i + offset + 1)
- else:
- # Start with a regular graph of (d - 1) degrees
- offset = (d - 1) // 2
- for i in range(n):
- for j in range(1, offset + 1):
- H.add_edge(i, (i - j) % n)
- H.add_edge(i, (i + j) % n)
- half = n // 2
- for i in range(0, m - n * offset):
- # add the remaining m - n*offset edges between i and i+half
- H.add_edge(i, (i + half) % n)
- return H
- def hkn_harary_graph(k, n, create_using=None):
- """Returns the Harary graph with given node connectivity and node number.
- The Harary graph $H_{k,n}$ is the graph that minimizes the number of
- edges needed with given node connectivity $k$ and node number $n$.
- This smallest number of edges is known to be ceil($kn/2$) [1]_.
- Parameters
- ----------
- k: integer
- The node connectivity of the generated graph
- n: integer
- The number of nodes the generated graph is to contain
- create_using : NetworkX graph constructor, optional Graph type
- to create (default=nx.Graph). If graph instance, then cleared
- before populated.
- Returns
- -------
- NetworkX graph
- The Harary graph $H_{k,n}$.
- See Also
- --------
- hnm_harary_graph
- Notes
- -----
- This algorithm runs in $O(kn)$ time.
- It is implemented by following the Reference [2]_.
- References
- ----------
- .. [1] Weisstein, Eric W. "Harary Graph." From MathWorld--A Wolfram Web
- Resource. http://mathworld.wolfram.com/HararyGraph.html.
- .. [2] Harary, F. "The Maximum Connectivity of a Graph."
- Proc. Nat. Acad. Sci. USA 48, 1142-1146, 1962.
- """
- if k < 1:
- raise NetworkXError("The node connectivity must be >= 1!")
- if n < k + 1:
- raise NetworkXError("The number of nodes must be >= k+1 !")
- # in case of connectivity 1, simply return the path graph
- if k == 1:
- H = nx.path_graph(n, create_using)
- return H
- # Construct an empty graph with n nodes first
- H = nx.empty_graph(n, create_using)
- # Test the parity of k and n
- if (k % 2 == 0) or (n % 2 == 0):
- # Construct a regular graph with k degrees
- offset = k // 2
- for i in range(n):
- for j in range(1, offset + 1):
- H.add_edge(i, (i - j) % n)
- H.add_edge(i, (i + j) % n)
- if k & 1:
- # odd degree; n must be even in this case
- half = n // 2
- for i in range(0, half):
- # add edges diagonally
- H.add_edge(i, i + half)
- else:
- # Construct a regular graph with (k - 1) degrees
- offset = (k - 1) // 2
- for i in range(n):
- for j in range(1, offset + 1):
- H.add_edge(i, (i - j) % n)
- H.add_edge(i, (i + j) % n)
- half = n // 2
- for i in range(0, half + 1):
- # add half+1 edges between i and i+half
- H.add_edge(i, (i + half) % n)
- return H
|