def test_valid_degree_sequence2(): n = 100 for i in range(10): G = nx.barabasi_albert_graph(n, 1) deg = (d for n, d in G.degree()) assert_true(nx.is_graphical(deg, method='eg')) assert_true(nx.is_graphical(deg, method='hh'))
def test_valid_degree_sequence1(): n = 100 p = .3 for i in range(10): G = nx.erdos_renyi_graph(n, p) deg = (d for n, d in G.degree()) assert_true(nx.is_graphical(deg, method='eg')) assert_true(nx.is_graphical(deg, method='hh'))
def test_numpy_degree_sequence(): try: import numpy except ImportError: return ds = numpy.array([1, 2, 2, 2, 1], dtype=numpy.int64) assert_true(nx.is_graphical(ds, 'eg')) assert_true(nx.is_graphical(ds, 'hh')) ds = numpy.array([1, 2, 2, 2, 1], dtype=numpy.float64) assert_true(nx.is_graphical(ds, 'eg')) assert_true(nx.is_graphical(ds, 'hh'))
def test_numpy_noninteger_degree_sequence(): try: import numpy except ImportError: raise nx.NetworkXError('make test pass by raising exception') ds = numpy.array([1.1, 2, 2, 2, 1], dtype=numpy.float64) a = nx.is_graphical(ds, 'eg')
def __init__(self, degree, rng): if not nx.is_graphical(degree): raise nx.NetworkXUnfeasible('degree sequence is not graphical') self.rng = rng self.degree = list(degree) # node labels are integers 0,...,n-1 self.m = sum(self.degree) / 2.0 # number of edges try: self.dmax = max(self.degree) # maximum degree except ValueError: self.dmax = 0
def test_small_graph_true(): z = [5, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1] assert_true(nx.is_graphical(z, method='hh')) assert_true(nx.is_graphical(z, method='eg')) z = [10, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2] assert_true(nx.is_graphical(z, method='hh')) assert_true(nx.is_graphical(z, method='eg')) z = [1, 1, 1, 1, 1, 2, 2, 2, 3, 4] assert_true(nx.is_graphical(z, method='hh')) assert_true(nx.is_graphical(z, method='eg'))
def test_small_graph_false(): z = [1000, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1] assert not nx.is_graphical(z, method='hh') assert not nx.is_graphical(z, method='eg') z = [6, 5, 4, 4, 2, 1, 1, 1] assert not nx.is_graphical(z, method='hh') assert not nx.is_graphical(z, method='eg') z = [1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4] assert not nx.is_graphical(z, method='hh') assert not nx.is_graphical(z, method='eg')
def test_small_graph_false(): z = [1000, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1] assert_false(nx.is_graphical(z, method='hh')) assert_false(nx.is_graphical(z, method='eg')) z = [6, 5, 4, 4, 2, 1, 1, 1] assert_false(nx.is_graphical(z, method='hh')) assert_false(nx.is_graphical(z, method='eg')) z = [1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4] assert_false(nx.is_graphical(z, method='hh')) assert_false(nx.is_graphical(z, method='eg'))
def from_degree_distribution(N, degree_dist, return_pos=False): number_of_nodes = N * np.array(degree_dist) degree_sequence = [] for i in range(int(math.floor(len(number_of_nodes)))): number_with_that_degree = number_of_nodes[i] for k in range(int(math.floor(number_with_that_degree))): degree_sequence.append(i) graphical = nx.is_graphical(degree_sequence) if not graphical: degree_sequence.append(1) G = nx.configuration_model(degree_sequence) try: G.remove_edges_from(nx.selfloop_edges(G)) except RuntimeError: print('No self loops to remove') if return_pos: pos = nx.spring_layout(G) return G, pos return G, None
def test_string_input(): a = nx.is_graphical([], 'foo')
def test_atlas(self): for graph in self.GAG: deg = (d for n, d in graph.degree()) assert_true(nx.is_graphical(deg, method='eg')) assert_true(nx.is_graphical(deg, method='hh'))
def test_non_integer_input(): a = nx.is_graphical([72.5], 'hh')
def test_negative_input(): assert_false(nx.is_graphical([-1], 'hh')) assert_false(nx.is_graphical([-1], 'eg'))
def test_negative_input(): assert not nx.is_graphical([-1], 'hh') assert not nx.is_graphical([-1], 'eg')
def test_atlas(self): for graph in self.GAG: deg = (d for n, d in graph.degree()) assert nx.is_graphical(deg, method="eg") assert nx.is_graphical(deg, method="hh")
G.add_edge(3, 4) G.add_edge(5, 4) #print(G.edges()) #print(G.nodes()) #nx.draw(G,with_labels=1) Z = nx.Graph() Z.add_node(1) Z.add_node(2) Z.add_node(3) Z.add_node(4) Z.add_node(5) Z.add_node(6) Z.add_edge(1, 2) Z.add_edge(3, 2) Z.add_edge(4, 2) Z.add_edge(5, 2) Z.add_edge(6, 2) #nx.draw(Z,with_labels=1,node_color='g') #print(Z.nodes()) #K=nx.complete_graph(25) #nx.draw(K,with_labels=1,node_color='r') M = nx.complete_graph(70) pos = nx.circular_layout(M) nx.draw(M, pos, with_labels=1, node_color='g') print(M.order()) l = [2, 2, 2, 1] print(nx.is_graphical(l))
""" =============== Degree Sequence =============== Random graph from given degree sequence. """ import matplotlib.pyplot as plt import networkx as nx # Specify seed for reproducibility seed = 668273 z = [5, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1] print(nx.is_graphical(z)) print("Configuration model") G = nx.configuration_model( z, seed=seed) # configuration model, seed for reproduciblity degree_sequence = [d for n, d in G.degree()] # degree sequence print(f"Degree sequence {degree_sequence}") print("Degree histogram") hist = {} for d in degree_sequence: if d in hist: hist[d] += 1 else: hist[d] = 1 print("degree #nodes") for d in hist: print(f"{d:4} {hist[d]:6}")
def havel_hakimi_graph(deg_sequence, create_using=None): """Return a simple graph with given degree sequence constructed using the Havel-Hakimi algorithm. Parameters ---------- deg_sequence: list of integers Each integer corresponds to the degree of a node (need not be sorted). create_using : NetworkX graph constructor, optional (default=nx.Graph) Graph type to create. If graph instance, then cleared before populated. Directed graphs are not allowed. Raises ------ NetworkXException For a non-graphical degree sequence (i.e. one not realizable by some simple graph). Notes ----- The Havel-Hakimi algorithm constructs a simple graph by successively connecting the node of highest degree to other nodes of highest degree, resorting remaining nodes by degree, and repeating the process. The resulting graph has a high degree-associativity. Nodes are labeled 1,.., len(deg_sequence), corresponding to their position in deg_sequence. The basic algorithm is from Hakimi [1]_ and was generalized by Kleitman and Wang [2]_. References ---------- .. [1] Hakimi S., On Realizability of a Set of Integers as Degrees of the Vertices of a Linear Graph. I, Journal of SIAM, 10(3), pp. 496-506 (1962) .. [2] Kleitman D.J. and Wang D.L. Algorithms for Constructing Graphs and Digraphs with Given Valences and Factors Discrete Mathematics, 6(1), pp. 79-88 (1973) """ if not nx.is_graphical(deg_sequence): raise nx.NetworkXError('Invalid degree sequence') p = len(deg_sequence) G = nx.empty_graph(p, create_using) if G.is_directed(): raise nx.NetworkXError("Directed graphs are not supported") num_degs = [[] for i in range(p)] dmax, dsum, n = 0, 0, 0 for d in deg_sequence: # Process only the non-zero integers if d > 0: num_degs[d].append(n) dmax, dsum, n = max(dmax, d), dsum + d, n + 1 # Return graph if no edges if n == 0: return G modstubs = [(0, 0)] * (dmax + 1) # Successively reduce degree sequence by removing the maximum degree while n > 0: # Retrieve the maximum degree in the sequence while len(num_degs[dmax]) == 0: dmax -= 1 # If there are not enough stubs to connect to, then the sequence is # not graphical if dmax > n - 1: raise nx.NetworkXError('Non-graphical integer sequence') # Remove largest stub in list source = num_degs[dmax].pop() n -= 1 # Reduce the next dmax largest stubs mslen = 0 k = dmax for i in range(dmax): while len(num_degs[k]) == 0: k -= 1 target = num_degs[k].pop() G.add_edge(source, target) n -= 1 if k > 1: modstubs[mslen] = (k - 1, target) mslen += 1 # Add back to the list any nonzero stubs that were removed for i in range(mslen): (stubval, stubtarget) = modstubs[i] num_degs[stubval].append(stubtarget) n += 1 return G
def havel_hakimi_custom_graph(deg_sequence): """Return a simple graph with given degree sequence constructed using a variant of the Havel-Hakimi algorithm. Parameters ---------- deg_sequence: list of integers Each integer corresponds to the degree of a node (need not be sorted). Raises ------ NetworkXException For a non-graphical degree sequence (i.e. one not realizable by some simple graph). Notes ----- The Havel-Hakimi algorithm constructs a simple graph by successively connecting the node of highest degree to other nodes of highest degree, resorting remaining nodes by degree, and repeating the process. The resulting graph has a high degree-associativity. Here we connect the node of lowest degree to the nodes of highest degree in order to get a connected graph. Nodes are labeled 1,.., len(deg_sequence), corresponding to their position in deg_sequence. The basic algorithm is from Hakimi [1]_ and was generalized by Kleitman and Wang [2]_. References ---------- .. [1] Hakimi S., On Realizability of a Set of Integers as Degrees of the Vertices of a Linear Graph. I, Journal of SIAM, 10(3), pp. 496-506 (1962) .. [2] Kleitman D.J. and Wang D.L. Algorithms for Constructing Graphs and Digraphs with Given Valences and Factors Discrete Mathematics, 6(1), pp. 79-88 (1973) """ if not (nx.is_valid_degree_sequence(deg_sequence) or nx.is_graphical(deg_sequence) or nx.is_valid_degree_sequence_erdos_gallai(deg_sequence)): raise nx.NetworkXError('Invalid degree sequence') p = len(deg_sequence) G=nx.empty_graph(p) num_degs = [] for i in range(p): num_degs.append([]) dmin, dmax, dsum, n = 10000000, 0, 0, 0 for d in deg_sequence: # Process only the non-zero integers if d>0: num_degs[d].append(n) dmin, dmax, dsum, n = min(dmin,d), max(dmax,d), dsum+d, n+1 # Return graph if no edges if n==0: return G modstubs = [(0,0)]*(dmax+1) # Successively reduce degree sequence by removing the maximum degree while n > 0: # Retrieve the maximum degree in the sequence while len(num_degs[dmax]) == 0: dmax -= 1; while len(num_degs[dmin]) == 0: dmax += 1; # If there are not enough stubs to connect to, then the sequence is # not graphical if dmax > n-1: raise nx.NetworkXError('Non-graphical integer sequence') # Remove most little stub in list source = num_degs[dmin].pop() n -= 1 # Reduce the dmin largest stubs mslen = 0 k = dmax for i in range(dmin): while len(num_degs[k]) == 0: k -= 1 target = num_degs[k].pop() G.add_edge(source, target) n -= 1 if k > 1: modstubs[mslen] = (k-1,target) mslen += 1 # Add back to the list any nonzero stubs that were removed for i in range(mslen): (stubval, stubtarget) = modstubs[i] num_degs[stubval].append(stubtarget) n += 1 G.name="havel_hakimi_graph %d nodes %d edges"%(G.order(),G.size()) return G
def test_negative_input(): assert not nx.is_graphical([-1], "hh") assert not nx.is_graphical([-1], "eg")
def havel_hakimi_graph(deg_sequence, create_using=None): """Returns a simple graph with given degree sequence constructed using the Havel-Hakimi algorithm. Parameters ---------- deg_sequence: list of integers Each integer corresponds to the degree of a node (need not be sorted). create_using : NetworkX graph constructor, optional (default=nx.Graph) Graph type to create. If graph instance, then cleared before populated. Directed graphs are not allowed. Raises ------ NetworkXException For a non-graphical degree sequence (i.e. one not realizable by some simple graph). Notes ----- The Havel-Hakimi algorithm constructs a simple graph by successively connecting the node of highest degree to other nodes of highest degree, resorting remaining nodes by degree, and repeating the process. The resulting graph has a high degree-associativity. Nodes are labeled 1,.., len(deg_sequence), corresponding to their position in deg_sequence. The basic algorithm is from Hakimi [1]_ and was generalized by Kleitman and Wang [2]_. References ---------- .. [1] Hakimi S., On Realizability of a Set of Integers as Degrees of the Vertices of a Linear Graph. I, Journal of SIAM, 10(3), pp. 496-506 (1962) .. [2] Kleitman D.J. and Wang D.L. Algorithms for Constructing Graphs and Digraphs with Given Valences and Factors Discrete Mathematics, 6(1), pp. 79-88 (1973) """ if not nx.is_graphical(deg_sequence): raise nx.NetworkXError("Invalid degree sequence") p = len(deg_sequence) G = nx.empty_graph(p, create_using) if G.is_directed(): raise nx.NetworkXError("Directed graphs are not supported") num_degs = [[] for i in range(p)] dmax, dsum, n = 0, 0, 0 for d in deg_sequence: # Process only the non-zero integers if d > 0: num_degs[d].append(n) dmax, dsum, n = max(dmax, d), dsum + d, n + 1 # Return graph if no edges if n == 0: return G modstubs = [(0, 0)] * (dmax + 1) # Successively reduce degree sequence by removing the maximum degree while n > 0: # Retrieve the maximum degree in the sequence while len(num_degs[dmax]) == 0: dmax -= 1 # If there are not enough stubs to connect to, then the sequence is # not graphical if dmax > n - 1: raise nx.NetworkXError("Non-graphical integer sequence") # Remove largest stub in list source = num_degs[dmax].pop() n -= 1 # Reduce the next dmax largest stubs mslen = 0 k = dmax for i in range(dmax): while len(num_degs[k]) == 0: k -= 1 target = num_degs[k].pop() G.add_edge(source, target) n -= 1 if k > 1: modstubs[mslen] = (k - 1, target) mslen += 1 # Add back to the list any nonzero stubs that were removed for i in range(mslen): (stubval, stubtarget) = modstubs[i] num_degs[stubval].append(stubtarget) n += 1 return G