# Ticket #7724: trac_7724_iterator-rebased.patch

File trac_7724_iterator-rebased.patch, 12.5 KB (added by rlm, 11 years ago)
• ## sage/graphs/base/c_graph.pyx

```# HG changeset patch
# User Yann Laigle-Chapuy <yannlaiglechapuy@gmail.com>
# Date 1261410197 -3600
# Node ID b66143e70dba9437c95d1f33dbfa26959097db54
# Parent  2a0d2c20d545899643823ba6cb346ac9774125c0
#7724 depth_first_search iterator

diff -r 2a0d2c20d545 -r b66143e70dba sage/graphs/base/c_graph.pyx```
 a return shortest_path def depth_first_search(self, v, reverse=False, ignore_direction=False): r""" Returns a depth-first search from vertex v. INPUT: - ``reverse`` -- considers the reversed graph ( the out_neighbors become in_neighbors ). The default value is ``False``. - ``ignore_direction`` -- consider the undirected graph. The default value is ``False``. EXAMPLE:: sage: G = Graph(graphs.PetersenGraph(), implementation='c_graph') sage: list(G.depth_first_search(0)) [0, 5, 8, 6, 9, 7, 2, 3, 4, 1] """ return Search_iterator(self, v, direction=-1, reverse=reverse, ignore_direction=ignore_direction) def breadth_first_search(self, v, reverse=False, ignore_direction=False): r""" Returns a breadth-first search from vertex v. INPUT: - ``reverse`` -- considers the reversed graph ( the out_neighbors become in_neighbors ). The default value is ``False``. - ``ignore_direction`` -- consider the undirected graph. The default value is ``False``. EXAMPLE:: sage: G = Graph(graphs.PetersenGraph(), implementation='c_graph') sage: list(G.breadth_first_search(0)) [0, 1, 4, 5, 2, 6, 3, 9, 7, 8] """ return Search_iterator(self, v, direction=0, reverse=reverse, ignore_direction=ignore_direction) def is_connected(self): r""" Returns whether the graph is connected. EXAMPLE: Petersen's graph is connected :: sage: DiGraph(graphs.PetersenGraph(),implementation="c_graph").is_connected() True While the disjoint union of two of them is not:: sage: DiGraph(2*graphs.PetersenGraph(),implementation="c_graph").is_connected() False """ cdef int v_int = 0 v_int = bitset_first((self._cg).active_vertices) if v_int == -1: return True return len(list(self.depth_first_search(get_vertex(v_int, self.vertex_ints, self.vertex_labels, self._cg),\ ignore_direction=True))\ ) == (self._cg).num_verts def is_strongly_connected(self): r""" Returns whether the graph is strongly connected. EXAMPLE: The circuit on 3 vertices is obviously strongly connected :: sage: g = DiGraph({ 0 : [1], 1 : [2], 2 : [0]},implementation="c_graph") sage: g.is_strongly_connected() True But a transitive triangle is not:: sage: g = DiGraph({ 0 : [1,2], 1 : [2]},implementation="c_graph") sage: g.is_strongly_connected() False """ cdef int v_int = 0 # Pick one vertex v_int = bitset_first((self._cg).active_vertices) if v_int == -1: return True v = get_vertex(v_int, self.vertex_ints, self.vertex_labels, self._cg) return (self._cg).num_verts == len(list(self.depth_first_search(v))) and \ (self._cg).num_verts == len(list(self.depth_first_search(v, reverse=True))) cdef class Search_iterator: cdef graph cdef int direction cdef list stack cdef bitset_t seen cdef bool test_out cdef bool test_in def __init__(self, graph, v, direction=0, reverse=False, ignore_direction=False): self.graph = graph self.direction = direction bitset_init(self.seen,(self.graph._cg).active_vertices.size) bitset_set_first_n(self.seen,0) self.stack = [get_vertex(v, self.graph.vertex_ints, self.graph.vertex_labels, self.graph._cg)] if not self.graph.directed: ignore_direction = False self.test_out = (not reverse) or ignore_direction self.test_in = reverse or ignore_direction def __iter__(self): return self def __next__(self): cdef int v_int cdef int w_int while self.stack: v_int = self.stack.pop(self.direction) if bitset_not_in(self.seen,v_int): value = vertex_label(v_int, self.graph.vertex_ints, self.graph.vertex_labels, self.graph._cg) bitset_add(self.seen,v_int) if self.test_out: self.stack.extend(self.graph._cg.out_neighbors(v_int)) if self.test_in: self.stack.extend(self.graph._cg.in_neighbors(v_int)) break else: bitset_free(self.seen) raise StopIteration return value
• ## sage/graphs/graph.py

`diff -r 2a0d2c20d545 -r b66143e70dba sage/graphs/graph.py`
 a """ if self.order() == 0: return True v = self.vertex_iterator().next() conn_verts = list(self.breadth_first_search(v, ignore_direction=True)) return len(conn_verts) == self.num_verts() try: return self._backend.is_connected() except AttributeError: v = self.vertex_iterator().next() conn_verts = list(self.depth_first_search(v, ignore_direction=True)) return len(conn_verts) == self.num_verts() def connected_components(self): """ sage: D.connected_component_containing_vertex(0) [0, 1, 2, 3] """ c = list(self.breadth_first_search(vertex, ignore_direction=True)) try: c = list(self._backend.depth_first_search(vertex, ignore_direction=True)) except AttributeError: c = list(self.depth_first_search(vertex, ignore_direction=True)) c.sort() return c [0, 1, 2] """ if neighbors is None: if not self._directed or ignore_direction: neighbors=self.neighbor_iterator else: neighbors=self.neighbor_out_iterator seen=set([]) if isinstance(start, list): queue=[(v,0) for v in start] else: queue=[(start,0)] for v,d in queue: yield v seen.add(v) while len(queue)>0: v,d = queue.pop(0) if distance is None or d0: v,d = queue.pop(0) if distance is None or d0: v,d = queue.pop() if v not in seen: yield v seen.add(v) if distance is None or d0: v,d = queue.pop() if v not in seen: yield v seen.add(v) if distance is None or d