def make_small_graph(graph_description, create_using=None): if graph_description[0] not in ("adjacencylist", "edgelist"): raise NetworkXError("ltype must be either adjacencylist or edgelist") ltype = graph_description[0] name = graph_description[1] n = graph_description[2] G = empty_graph(n, create_using) nodes = G.nodes() if ltype == "adjacencylist": adjlist = graph_description[3] if len(adjlist) != n: raise NetworkXError("invalid graph_description") G.add_edges_from([(u - 1, v) for v in nodes for u in adjlist[v]]) elif ltype == "edgelist": edgelist = graph_description[3] for e in edgelist: v1 = e[0] - 1 v2 = e[1] - 1 if v1 < 0 or v1 > n - 1 or v2 < 0 or v2 > n - 1: raise NetworkXError("invalid graph_description") G.add_edge(v1, v2) G.name = name return G
def turan_graph(n, r): if not 1 <= r <= n: raise NetworkXError("Must satisfy 1 <= r <= n") partitions = [n // r] * (r - (n % r)) + [n // r + 1] * (n % r) G = complete_multipartite_graph(*partitions) return G
def complete_multipartite_graph(*subset_sizes): # The complete multipartite graph is an undirected simple graph. G = Graph() if len(subset_sizes) == 0: return G # set up subsets of nodes try: extents = pairwise(accumulate((0, ) + subset_sizes)) subsets = [range(start, end) for start, end in extents] except TypeError: subsets = subset_sizes # add nodes with subset attribute # while checking that ints are not mixed with iterables try: for (i, subset) in enumerate(subsets): G.add_nodes_from(subset, subset=i) except TypeError: raise NetworkXError("Arguments must be all ints or all iterables") # Across subsets, all vertices should be adjacent. # We can use itertools.combinations() because undirected. for subset1, subset2 in itertools.combinations(subsets, 2): G.add_edges_from(itertools.product(subset1, subset2)) return G
def ladder_graph(n, create_using=None): G = empty_graph(2 * n, create_using) if G.is_directed(): raise NetworkXError("Directed Graph not supported") G.add_edges_from(pairwise(range(n))) G.add_edges_from(pairwise(range(n, 2 * n))) G.add_edges_from((v, v + n) for v in range(n)) return G
def make_small_undirected_graph(graph_description, create_using=None): """ Return a small undirected graph described by graph_description. See make_small_graph. """ G = empty_graph(0, create_using) if G.is_directed(): raise NetworkXError("Directed Graph not supported") return make_small_graph(graph_description, G)
def star_graph(n, create_using=None): n_name, nodes = n if isinstance(n_name, int): nodes = nodes + [n_name] # there should be n+1 nodes first = nodes[0] G = empty_graph(nodes, create_using) if G.is_directed(): raise NetworkXError("Directed Graph not supported") G.add_edges_from((first, v) for v in nodes[1:]) return G
def dorogovtsev_goltsev_mendes_graph(n, create_using=None): G = empty_graph(0, create_using) if G.is_directed(): raise NetworkXError("Directed Graph not supported") if G.is_multigraph(): raise NetworkXError("Multigraph not supported") G.add_edge(0, 1) if n == 0: return G new_node = 2 # next node to be added for i in range(1, n + 1): # iterate over number of generations. last_generation_edges = list(G.edges()) number_of_edges_in_last_generation = len(last_generation_edges) for j in range(0, number_of_edges_in_last_generation): G.add_edge(new_node, last_generation_edges[j][0]) G.add_edge(new_node, last_generation_edges[j][1]) new_node += 1 return G
def barbell_graph(m1, m2, create_using=None): if m1 < 2: raise NetworkXError("Invalid graph description, m1 should be >=2") if m2 < 0: raise NetworkXError("Invalid graph description, m2 should be >=0") # left barbell G = complete_graph(m1, create_using) if G.is_directed(): raise NetworkXError("Directed Graph not supported") # connecting path G.add_nodes_from(range(m1, m1 + m2 - 1)) if m2 > 1: G.add_edges_from(pairwise(range(m1, m1 + m2))) # right barbell G.add_edges_from((u, v) for u in range(m1 + m2, 2 * m1 + m2) for v in range(u + 1, 2 * m1 + m2)) # connect it up G.add_edge(m1 - 1, m1) if m2 > 0: G.add_edge(m1 + m2 - 1, m1 + m2) return G
def lollipop_graph(m, n, create_using=None): m, m_nodes = m n, n_nodes = n M = len(m_nodes) N = len(n_nodes) if isinstance(m, int): n_nodes = [len(m_nodes) + i for i in n_nodes] if M < 2: raise NetworkXError("Invalid graph description, m should be >=2") if N < 0: raise NetworkXError("Invalid graph description, n should be >=0") # the ball G = complete_graph(m_nodes, create_using) if G.is_directed(): raise NetworkXError("Directed Graph not supported") # the stick G.add_nodes_from(n_nodes) if N > 1: G.add_edges_from(pairwise(n_nodes)) # connect ball to stick if M > 0 and N > 0: G.add_edge(m_nodes[-1], n_nodes[0]) return G
def LCF_graph(n, shift_list, repeats, create_using=None): if n <= 0: return empty_graph(0, create_using) # start with the n-cycle G = cycle_graph(n, create_using) if G.is_directed(): raise NetworkXError("Directed Graph not supported") G.name = "LCF_graph" nodes = sorted(list(G)) n_extra_edges = repeats * len(shift_list) # edges are added n_extra_edges times # (not all of these need be new) if n_extra_edges < 1: return G for i in range(n_extra_edges): shift = shift_list[i % len(shift_list)] # cycle through shift_list v1 = nodes[i % n] # cycle repeatedly through nodes v2 = nodes[(i + shift) % n] G.add_edge(v1, v2) return G
def predecessors(self, n): try: return iter(self._pred[n]) except KeyError: raise NetworkXError("The node %s is not in the digraph." % (n, ))