def _single_source_dijkstra_path_basic(G, s, weight): # modified from Eppstein S = [] P = {} for v in G: P[v] = [] sigma = dict.fromkeys(G, 0.0) # sigma[v]=0 for v in G D = {} sigma[s] = 1.0 push = heappush pop = heappop seen = {s: 0} c = count() Q = [] # use Q as heap with (distance,node id) tuples push(Q, (0, next(c), s, s)) while Q: (dist, _, pred, v) = pop(Q) if v in D: continue # already searched this node. sigma[v] += sigma[pred] # count paths S.append(v) D[v] = dist for w, edgedata in G[v].items(): vw_dist = dist + edgedata.get(weight, 1) if w not in D and (w not in seen or vw_dist < seen[w]): seen[w] = vw_dist push(Q, (vw_dist, next(c), v, w)) sigma[w] = 0.0 P[w] = [v] elif vw_dist == seen[w]: # handle equal paths sigma[w] += sigma[v] P[w].append(v) return S, P, sigma
def parseData(): """Return stream of pairs b[i], x[i] for sparse6 format.""" chunks = iter(data) d = None # partial data word dLen = 0 # how many unparsed bits are left in d while 1: if dLen < 1: try: d = next(chunks) except StopIteration: return dLen = 6 dLen -= 1 b = (d >> dLen) & 1 # grab top remaining bit x = d & ((1 << dLen) - 1) # partially built up value of x xLen = dLen # how many bits included so far in x while xLen < k: # now grab full chunks until we have enough try: d = next(chunks) except StopIteration: return dLen = 6 x = (x << 6) + d xLen += 6 x = (x >> (xLen - k)) # shift back the extra bits dLen = xLen - k yield b, x
def parse_kv(curr_token): dct = defaultdict(list) while curr_token[0] == 0: # keys key = curr_token[1] curr_token = next(tokens) category = curr_token[0] if category == 1 or category == 2: # reals or ints value = curr_token[1] curr_token = next(tokens) elif category == 3: # strings value = unescape(curr_token[1][1:-1]) if destringizer: try: value = destringizer(value) except ValueError: pass curr_token = next(tokens) elif category == 4: # dict start curr_token, value = parse_dict(curr_token) else: unexpected(curr_token, "an int, float, string or '['") dct[key].append(value) dct = dict((key, (value if not isinstance(value, list) or len(value) != 1 else value[0])) for key, value in dct.items()) return curr_token, dct
def test_shortest_simple_paths(): G = cnlti(nx.grid_2d_graph(4, 4), first_label=1, ordering="sorted") paths = nx.shortest_simple_paths(G, 1, 12) assert_equal(next(paths), [1, 2, 3, 4, 8, 12]) assert_equal(next(paths), [1, 5, 6, 7, 8, 12]) assert_equal([len(path) for path in nx.shortest_simple_paths(G, 1, 12)], sorted([len(path) for path in nx.all_simple_paths(G, 1, 12)]))
def _alternating_dfs(u, along_matched=True): """Returns True if and only if `u` is connected to one of the targets by an alternating path. `u` is a vertex in the graph `G`. If `along_matched` is True, this step of the depth-first search will continue only through edges in the given matching. Otherwise, it will continue only through edges *not* in the given matching. """ if along_matched: edges = itertools.cycle([matched_edges, unmatched_edges]) else: edges = itertools.cycle([unmatched_edges, matched_edges]) visited = set() stack = [(u, iter(G[u]), next(edges))] while stack: parent, children, valid_edges = stack[-1] try: child = next(children) if child not in visited: if ((parent, child) in valid_edges or (child, parent) in valid_edges): if child in targets: return True visited.add(child) stack.append((child, iter(G[child]), next(edges))) except StopIteration: stack.pop() return False
def parse_p2g(lines): """Parse p2g format graph from string or iterable. Returns ------- MultiDiGraph """ description = next(lines).strip() # are multiedges (parallel edges) allowed? G = networkx.MultiDiGraph(name=description, selfloops=True) nnodes, nedges = map(int, next(lines).split()) nodelabel = {} nbrs = {} # loop over the nodes keeping track of node labels and out neighbors # defer adding edges until all node labels are known for i in range(nnodes): n = next(lines).strip() nodelabel[i] = n G.add_node(n) nbrs[n] = map(int, next(lines).split()) # now we know all of the node labels so we can add the edges # with the correct labels for n in G: for nbr in nbrs[n]: G.add_edge(n, nodelabel[nbr]) return G
def has_bridges(G, root=None): """Decide whether a graph has any bridges. A *bridge* in a graph is an edge whose removal causes the number of connected components of the graph to increase. Parameters ---------- G : undirected graph root : node (optional) A node in the graph `G`. If specified, only the bridges in the connected component containing this node will be considered. Returns ------- bool Whether the graph (or the connected component containing `root`) has any bridges. Raises ------ NodeNotFound If `root` is not in the graph `G`. Examples -------- The barbell graph with parameter zero has a single bridge:: >>> G = nx.barbell_graph(10, 0) >>> nx.has_bridges(G) True On the other hand, the cycle graph has no bridges:: >>> G = nx.cycle_graph(5) >>> nx.has_bridges(G) False Notes ----- This implementation uses the :func:`networkx.bridges` function, so it shares its worst-case time complexity, $O(m + n)$, ignoring polylogarithmic factors, where $n$ is the number of nodes in the graph and $m$ is the number of edges. """ try: next(bridges(G)) except StopIteration: return False else: return True
def cycles(seq): """Yields cyclic permutations of the given sequence. For example:: >>> list(cycles('abc')) [('a', 'b', 'c'), ('b', 'c', 'a'), ('c', 'a', 'b')] """ n = len(seq) cycled_seq = cycle(seq) for x in seq: yield tuple(islice(cycled_seq, n)) next(cycled_seq)
def check_counterexample(G, sub_graph): """Raises an exception if the counterexample is wrong. Parameters ---------- G : NetworkX graph subdivision_nodes : set A set of nodes inducing a subgraph as a counterexample """ # 1. Create the sub graph sub_graph = nx.Graph(sub_graph) # 2. Remove self loops for u in sub_graph: if sub_graph.has_edge(u, u): sub_graph.remove_edge(u, u) # keep track of nodes we might need to contract contract = list(sub_graph) # 3. Contract Edges while len(contract) > 0: contract_node = contract.pop() if contract_node not in sub_graph: # Node was already contracted continue degree = sub_graph.degree[contract_node] # Check if we can remove the node if degree == 2: # Get the two neighbors neighbors = iter(sub_graph[contract_node]) u = next(neighbors) v = next(neighbors) # Save nodes for later contract.append(u) contract.append(v) # Contract edge sub_graph.remove_node(contract_node) sub_graph.add_edge(u, v) # 4. Check for isomorphism with K5 or K3_3 graphs if len(sub_graph) == 5: if not nx.is_isomorphic(nx.complete_graph(5), sub_graph): raise nx.NetworkXException("Bad counter example.") elif len(sub_graph) == 6: if not nx.is_isomorphic(nx.complete_bipartite_graph(3, 3), sub_graph): raise nx.NetworkXException("Bad counter example.") else: raise nx.NetworkXException("Bad counter example.")
def test_iter(self): nv = self.nv for i, n in enumerate(nv): assert_equal(i, n) inv = iter(nv) assert_equal(next(inv), 0) assert_not_equal(iter(nv), nv) assert_equal(iter(inv), inv) inv2 = iter(nv) next(inv2) assert_equal(list(inv), list(inv2)) # odd case where NodeView calls NodeDataView with data=False nnv = nv(data=False) for i, n in enumerate(nnv): assert_equal(i, n)
def pairwise(iterable, cyclic=False): "s -> (s0, s1), (s1, s2), (s2, s3), ..." a, b = tee(iterable) first = next(b, None) if cyclic is True: return zip(a, chain(b, (first, ))) return zip(a, b)
def arbitrary_element(iterable): """Returns an arbitrary element of `iterable` without removing it. This is most useful for "peeking" at an arbitrary element of a set, but can be used for any list, dictionary, etc., as well:: >>> arbitrary_element({3, 2, 1}) 1 >>> arbitrary_element('hello') 'h' This function raises a :exc:`ValueError` if `iterable` is an iterator (because the current implementation of this function would consume an element from the iterator):: >>> iterator = iter([1, 2, 3]) >>> arbitrary_element(iterator) Traceback (most recent call last): ... ValueError: cannot return an arbitrary item from an iterator """ if is_iterator(iterable): raise ValueError('cannot return an arbitrary item from an iterator') # Another possible implementation is ``for x in iterable: return x``. return next(iter(iterable))
def add_path(G_to_add_to, nodes_for_path, **attr): """Add a path to the Graph G_to_add_to. Parameters ---------- G_to_add_to : graph A NetworkX graph nodes_for_path : iterable container A container of nodes. A path will be constructed from the nodes (in order) and added to the graph. attr : keyword arguments, optional (default= no attributes) Attributes to add to every edge in path. See Also -------- add_star, add_cycle Examples -------- >>> G = nx.Graph() >>> nx.add_path(G, [0, 1, 2, 3]) >>> nx.add_path(G, [10, 11, 12], weight=7) """ nlist = iter(nodes_for_path) try: first_node = next(nlist) except StopIteration: return G_to_add_to.add_node(first_node) G_to_add_to.add_edges_from(pairwise(chain((first_node, ), nlist)), **attr)
def add_star(G_to_add_to, nodes_for_star, **attr): """Add a star to Graph G_to_add_to. The first node in `nodes_for_star` is the middle of the star. It is connected to all other nodes. Parameters ---------- G_to_add_to : graph A NetworkX graph nodes_for_star : iterable container A container of nodes. attr : keyword arguments, optional (default= no attributes) Attributes to add to every edge in star. See Also -------- add_path, add_cycle Examples -------- >>> G = nx.Graph() >>> nx.add_star(G, [0, 1, 2, 3]) >>> nx.add_star(G, [10, 11, 12], weight=2) """ nlist = iter(nodes_for_star) v = next(nlist) edges = ((v, n) for n in nlist) G_to_add_to.add_edges_from(edges, **attr)
def subgraph_is_isomorphic(self): """Returns True if a subgraph of G1 is isomorphic to G2.""" try: x = next(self.subgraph_isomorphisms_iter()) return True except StopIteration: return False
def test_iter(self): nv = self.nv for i, (n, d) in enumerate(nv): assert_equal(i, n) assert_equal(d, {}) inv = iter(nv) assert_equal(next(inv), (0, {})) self.G.nodes[3]['foo'] = 'bar' # default for n, d in nv: if n == 3: assert_equal(d, {'foo': 'bar'}) else: assert_equal(d, {}) # data=True for n, d in self.ndv: if n == 3: assert_equal(d, {'foo': 'bar'}) else: assert_equal(d, {}) # data='foo' for n, d in self.nwv: if n == 3: assert_equal(d, 'bar') else: assert_equal(d, None) # data='foo', default=1 for n, d in self.G.nodes.data('foo', default=1): if n == 3: assert_equal(d, 'bar') else: assert_equal(d, 1)
def get_attr_id(self, title, attr_type, edge_or_node, default, mode): # find the id of the attribute or generate a new id try: return self.attr[edge_or_node][mode][title] except KeyError: # generate new id new_id = str(next(self.attr_id)) self.attr[edge_or_node][mode][title] = new_id attr_kwargs = {'id': new_id, 'title': title, 'type': attr_type} attribute = Element('attribute', **attr_kwargs) # add subelement for data default value if present default_title = default.get(title) if default_title is not None: default_element = Element('default') default_element.text = make_str(default_title) attribute.append(default_element) # new insert it into the XML attributes_element = None for a in self.graph_element.findall('attributes'): # find existing attributes element by class and mode a_class = a.get('class') a_mode = a.get('mode', 'static') if a_class == edge_or_node and a_mode == mode: attributes_element = a if attributes_element is None: # create new attributes element attr_kwargs = {'mode': mode, 'class': edge_or_node} attributes_element = Element('attributes', **attr_kwargs) self.graph_element.insert(0, attributes_element) attributes_element.append(attribute) return new_id
def disjoint_union_all(graphs): """Return the disjoint union of all graphs. This operation forces distinct integer node labels starting with 0 for the first graph in the list and numbering consecutively. Parameters ---------- graphs : list List of NetworkX graphs Returns ------- U : A graph with the same type as the first graph in list Raises ------ ValueError If `graphs` is an empty list. Notes ----- It is recommended that the graphs be either all directed or all undirected. Graph, edge, and node attributes are propagated to the union graph. If a graph attribute is present in multiple graphs, then the value from the last graph in the list with that attribute is used. """ if not graphs: raise ValueError('cannot apply disjoint_union_all to an empty list') graphs = iter(graphs) U = next(graphs) for H in graphs: U = nx.disjoint_union(U, H) return U
def test_articulation_points(): Ggen = _generate_no_biconnected() for i in range(1): # change 1 to 3 or more for more realizations. G = next(Ggen) articulation_points = list(set([a]) for a in nx.articulation_points(G)) for cut in nx.all_node_cuts(G): assert_true(cut in articulation_points)
def test_no_weight(self): inf = float('inf') expected = set([(3, 4, inf), (4, 3, inf)]) assert_in(next(nx.local_bridges(self.BB)), expected) expected = set([(u, v, 3) for u, v, in self.square.edges]) assert_equal(set(nx.local_bridges(self.square)), expected) assert_equal(list(nx.local_bridges(self.tri)), [])
def intersection_all(graphs): """Return a new graph that contains only the edges that exist in all graphs. All supplied graphs must have the same node set. Parameters ---------- graphs : list List of NetworkX graphs Returns ------- R : A new graph with the same type as the first graph in list Raises ------ ValueError If `graphs` is an empty list. Notes ----- Attributes from the graph, nodes, and edges are not copied to the new graph. """ if not graphs: raise ValueError('cannot apply intersection_all to an empty list') graphs = iter(graphs) R = next(graphs) for H in graphs: R = nx.intersection(R, H) return R
def _tree_edges(n, r): if n == 0: return # helper function for trees # yields edges in rooted tree at 0 with n nodes and branching ratio r nodes = iter(range(n)) parents = [next(nodes)] # stack of max length r while parents: source = parents.pop(0) for i in range(r): try: target = next(nodes) parents.append(target) yield source, target except StopIteration: break
def edge_key_data(G): # helper function to unify multigraph and graph edge iterator if G.is_multigraph(): for u, v, key, data in G.edges(data=True, keys=True): edge_data = data.copy() edge_data.update(key=key) edge_id = edge_data.pop('id', None) if edge_id is None: edge_id = next(self.edge_id) yield u, v, edge_id, edge_data else: for u, v, data in G.edges(data=True): edge_data = data.copy() edge_id = edge_data.pop('id', None) if edge_id is None: edge_id = next(self.edge_id) yield u, v, edge_id, edge_data
def insert(self, key, value, allow_increase=False): dict = self._dict if key in dict: old_value = dict[key] if value < old_value or (allow_increase and value > old_value): # Since there is no way to efficiently obtain the location of a # key-value pair in the heap, insert a new pair even if ones # with the same key may already be present. Deem the old ones # as stale and skip them when the minimum pair is queried. dict[key] = value heappush(self._heap, (value, next(self._count), key)) return value < old_value return False else: dict[key] = value heappush(self._heap, (value, next(self._count), key)) return True
def test_articulation_points(): Ggen = _generate_no_biconnected() for flow_func in flow_funcs: for i in range(3): G = next(Ggen) assert_equal(nx.node_connectivity(G, flow_func=flow_func), 1, msg=msg % (flow_func.__name__, ))
def suitable_edge(self): """Returns True if and only if an arbitrary remaining node can potentially be joined with some other remaining node. """ nodes = iter(self.remaining_degree) u = next(nodes) return any(v not in self.graph[u] for v in nodes)
def test_iter(self): ev = self.eview(self.G) for u, v, k in ev: pass iev = iter(ev) assert_equal(next(iev), (0, 1, 0)) assert_not_equal(iter(ev), ev) assert_equal(iter(iev), iev)
def test_iter(self): dv = self.dview(self.G) for n, d in dv: pass idv = iter(dv) assert_not_equal(iter(dv), dv) assert_equal(iter(idv), idv) assert_equal(next(idv), (0, dv[0])) assert_equal(next(idv), (1, dv[1])) # weighted dv = self.dview(self.G, weight='foo') for n, d in dv: pass idv = iter(dv) assert_not_equal(iter(dv), dv) assert_equal(iter(idv), idv) assert_equal(next(idv), (0, dv[0])) assert_equal(next(idv), (1, dv[1]))
def test_iter(self): evr = self.eview(self.G) ev = evr() for u, v in ev: pass iev = iter(ev) assert_equal(next(iev), (0, 1)) assert_not_equal(iter(ev), ev) assert_equal(iter(iev), iev)
def test_articulation_points(): Ggen = _generate_no_biconnected() for flow_func in flow_funcs: for i in range(1): # change 1 to 3 or more for more realizations. G = next(Ggen) cut = nx.minimum_node_cut(G, flow_func=flow_func) assert_true(len(cut) == 1, msg=msg % (flow_func.__name__, )) assert_true(cut.pop() in set(nx.articulation_points(G)), msg=msg % (flow_func.__name__, ))