def test_all_simple_edge_paths_corner_cases(self): assert list(nx.builtin.all_simple_edge_paths(nx.empty_graph(2), 0, 0)) == [] assert list(nx.builtin.all_simple_edge_paths(nx.empty_graph(2), 0, 1)) == [] assert list(nx.builtin.all_simple_edge_paths(nx.path_graph(9), 0, 8, 0)) == []
def test_small_graph_centrality(self): G = nx.empty_graph(create_using=nx.DiGraph) assert {} == nx.degree_centrality(G) assert {} == nx.out_degree_centrality(G) assert {} == nx.in_degree_centrality(G) G = nx.empty_graph(1, create_using=nx.DiGraph) assert {0: 1} == nx.degree_centrality(G) assert {0: 1} == nx.out_degree_centrality(G) assert {0: 1} == nx.in_degree_centrality(G)
def binomial_tree(n, create_using=None): G = nx.empty_graph(1, create_using) N = 1 for i in range(n): # Use G.edges() to ensure 2-tuples. G.edges is 3-tuple for MultiGraph edges = [(u + N, v + N) for (u, v) in G.edges()] G.add_edges_from(edges) G.add_edge(0, N) N *= 2 return G
def random_cograph(n, seed=None): R = nx.empty_graph(1) for i in range(n): RR = nx.relabel_nodes(R.copy(), lambda x: x + len(R)) if seed.randint(0, 1) == 0: R = full_join(R, RR) else: R = disjoint_union(R, RR) return R
def test_ladder_graph(self): for i, G in [ (0, nx.empty_graph(0)), (1, nx.path_graph(2)), ]: assert is_isomorphic(nx.ladder_graph(i), G) pytest.raises(nx.NetworkXError, nx.ladder_graph, 2, create_using=nx.DiGraph) g = nx.ladder_graph(2) mg = nx.ladder_graph(2, create_using=nx.MultiGraph) assert_edges_equal(mg.edges(), g.edges())
def random_k_out_graph(n, k, alpha, self_loops=True, seed=None): if alpha < 0: raise ValueError("alpha must be positive") G = nx.empty_graph(n, create_using=nx.MultiDiGraph) weights = Counter({v: alpha for v in G}) for i in range(k * n): u = seed.choice([v for v, d in G.out_degree() if d < k]) # If self-loops are not allowed, make the source node `u` have # weight zero. if not self_loops: adjustment = Counter({u: weights[u]}) else: adjustment = Counter() v = weighted_choice(weights - adjustment, seed=seed) G.add_edge(u, v) weights[v] += 1 return G
def parse_adjlist(lines, comments="#", delimiter=None, create_using=None, nodetype=None): G = nx.empty_graph(0, create_using) edges = [] nodes = [] # nodes that has not any adjacency for line in lines: p = line.find(comments) if p >= 0: line = line[:p] if not line: continue vlist = line.strip().split(delimiter) u = vlist.pop(0) # convert types if nodetype is not None: try: u = nodetype(u) except Exception as e: raise TypeError( "Failed to convert node ({}) to type {}".format( u, nodetype)) from e if len(vlist) == 0: nodes.append(u) if nodetype is not None: try: vlist = map(nodetype, vlist) except Exception as e: raise TypeError( "Failed to convert nodes ({}) to type {}".format( ",".join(vlist), nodetype)) from e edges.extend([u, v] for v in vlist) # N.B: batch add edges to graph. if nodes: G.add_nodes_from(nodes) G.add_edges_from(edges) return G
def random_uniform_k_out_graph(n, k, self_loops=True, with_replacement=True, seed=None): """Returns a random `k`-out graph with uniform attachment. A random `k`-out graph with uniform attachment is a multidigraph generated by the following algorithm. For each node *u*, choose `k` nodes *v* uniformly at random (with replacement). Add a directed edge joining *u* to *v*. Parameters ---------- n : int The number of nodes in the returned graph. k : int The out-degree of each node in the returned graph. self_loops : bool If True, self-loops are allowed when generating the graph. with_replacement : bool If True, neighbors are chosen with replacement and the returned graph will be a directed multigraph. Otherwise, neighbors are chosen without replacement and the returned graph will be a directed graph. seed : integer, random_state, or None (default) Indicator of random number generation state. See :ref:`Randomness<randomness>`. Returns ------- NetworkX graph A `k`-out-regular directed graph generated according to the above algorithm. It will be a multigraph if and only if `with_replacement` is True. Raises ------ ValueError If `with_replacement` is False and `k` is greater than `n`. See also -------- random_k_out_graph Notes ----- The return digraph or multidigraph may not be strongly connected, or even weakly connected. If `with_replacement` is True, this function is similar to :func:`random_k_out_graph`, if that function had parameter `alpha` set to positive infinity. """ if with_replacement: create_using = nx.MultiDiGraph() def sample(v, nodes): if not self_loops: nodes = nodes - {v} return (seed.choice(list(nodes)) for i in range(k)) else: create_using = nx.DiGraph() def sample(v, nodes): if not self_loops: nodes = nodes - {v} return seed.sample(nodes, k) G = nx.empty_graph(n, create_using) nodes = set(G) for u in G: G.add_edges_from((u, v) for v in sample(u, nodes)) return G
def scale_free_graph( n, alpha=0.41, beta=0.54, gamma=0.05, delta_in=0.2, delta_out=0, create_using=None, seed=None, ): def _choose_node(G, distribution, delta, psum): cumsum = 0.0 # normalization r = seed.random() for n, d in distribution: cumsum += (d + delta) / psum if r < cumsum: break return n if create_using is None or not hasattr(create_using, "_adj"): # start with 3-cycle G = nx.empty_graph(3, create_using, default=nx.MultiDiGraph) G.add_edges_from([(0, 1), (1, 2), (2, 0)]) else: G = create_using if not (G.is_directed() and G.is_multigraph()): raise nx.NetworkXError("MultiDiGraph required in create_using") if alpha <= 0: raise ValueError("alpha must be > 0.") if beta <= 0: raise ValueError("beta must be > 0.") if gamma <= 0: raise ValueError("gamma must be > 0.") if abs(alpha + beta + gamma - 1.0) >= 1e-9: raise ValueError("alpha+beta+gamma must equal 1.") number_of_edges = G.number_of_edges() while len(G) < n: psum_in = number_of_edges + delta_in * len(G) psum_out = number_of_edges + delta_out * len(G) r = seed.random() # random choice in alpha,beta,gamma ranges if r < alpha: # alpha # add new node v v = len(G) # choose w according to in-degree and delta_in w = _choose_node(G, G.in_degree(), delta_in, psum_in) elif r < alpha + beta: # beta # choose v according to out-degree and delta_out v = _choose_node(G, G.out_degree(), delta_out, psum_out) # choose w according to in-degree and delta_in w = _choose_node(G, G.in_degree(), delta_in, psum_in) else: # gamma # choose v according to out-degree and delta_out v = _choose_node(G, G.out_degree(), delta_out, psum_out) # add new node w w = len(G) G.add_edge(v, w) number_of_edges += 1 return G
def parse_edgelist( lines, comments="#", delimiter=None, create_using=None, nodetype=None, data=True, ): from ast import literal_eval G = nx.empty_graph(0, create_using) edges = [] for line in lines: p = line.find(comments) if p >= 0: line = line[:p] if not line: continue # split line, should have 2 or more s = line.strip().split(delimiter) if len(s) < 2: continue u = s.pop(0) v = s.pop(0) d = s if nodetype is not None: try: u = nodetype(u) v = nodetype(v) except Exception as e: raise TypeError( f"Failed to convert nodes {u},{v} to type {nodetype}." ) from e if len(d) == 0 or data is False: # no data or data type specified edgedata = {} elif data is True: # no edge types specified try: # try to evaluate as dictionary if delimiter == ",": edgedata_str = ",".join(d) else: edgedata_str = " ".join(d) edgedata = dict(literal_eval(edgedata_str.strip())) except Exception as e: raise TypeError( f"Failed to convert edge data ({d}) to dictionary.") from e else: # convert edge data to dictionary with specified keys and type if len(d) != len(data): raise IndexError( f"Edge data {d} and data_keys {data} are not the same length" ) edgedata = {} for (edge_key, edge_type), edge_value in zip(data, d): try: edge_value = edge_type(edge_value) except Exception as e: raise TypeError( f"Failed to convert {edge_key} data {edge_value} " f"to type {edge_type}.") from e edgedata.update({edge_key: edge_value}) edges.append((u, v, edgedata)) G.add_edges_from(edges) return G
def from_pandas_edgelist( df, source="source", target="target", edge_attr=None, create_using=None, edge_key=None, ): g = nx.empty_graph(0, create_using) if edge_attr is None: g.add_edges_from(zip(df[source], df[target])) return g reserved_columns = [source, target] # Additional columns requested attr_col_headings = [] attribute_data = [] if edge_attr is True: attr_col_headings = [ c for c in df.columns if c not in reserved_columns ] elif isinstance(edge_attr, (list, tuple)): attr_col_headings = edge_attr else: attr_col_headings = [edge_attr] if len(attr_col_headings) == 0: raise nx.NetworkXError( f"Invalid edge_attr argument: No columns found with name: {attr_col_headings}" ) try: attribute_data = zip(*[df[col] for col in attr_col_headings]) except (KeyError, TypeError) as e: msg = f"Invalid edge_attr argument: {edge_attr}" raise nx.NetworkXError(msg) from e if g.is_multigraph(): # => append the edge keys from the df to the bundled data if edge_key is not None: try: multigraph_edge_keys = df[edge_key] attribute_data = zip(attribute_data, multigraph_edge_keys) except (KeyError, TypeError) as e: msg = f"Invalid edge_key argument: {edge_key}" raise nx.NetworkXError(msg) from e for s, t, attrs in zip(df[source], df[target], attribute_data): if edge_key is not None: attrs, multigraph_edge_key = attrs key = g.add_edge(s, t, key=multigraph_edge_key) else: key = g.add_edge(s, t) g[s][t][key].update(zip(attr_col_headings, attrs)) else: edges = [] for s, t, attrs in zip(df[source], df[target], attribute_data): edges.append((s, t, zip(attr_col_headings, attrs))) g.add_edges_from(edges) return g