def test_all(): for directed in [True, False]: for (i, g) in enumerate([make_g1(directed), make_g2(directed)]): print("Processing G%s (directed = %s)" % (i, directed)) vis = MyDepthFirstSearchVisitor(verbose=False) map_color = defaultdict(int) depth_first_search(0, g, make_assoc_property_map(map_color), vis) n = num_vertices(g) m = num_edges(g) n_ = vis.num_vertices m_ = vis.num_edges # Our graph are connected, so these assertion should be verified assert n_ == n, "Visited %s/%s vertices" % (n_, n) if directed: assert m_ == m, "Visited %s/%s edges" % (m_, m) else: # Undirected edges are visited forward and backward, so they are visited "twice" # Not that (u -> u) arc would be only visited once. assert m_ == 2 * m, "Visited %s/%s edges" % (m_, m) # Finally, all vertices should all be BLACK for u in vertices(g): assert map_color[u] == BLACK
def test_isolated_vertices(): # Create 10 isolated vertices infty = sys.maxsize g = DirectedGraph(10) map_eweight = dict() for s in vertices(g): map_vpreds = defaultdict(set) map_vdist = dict() dijkstra_shortest_paths(g, s, make_assoc_property_map(map_eweight), make_assoc_property_map(map_vpreds), make_assoc_property_map(map_vdist)) # No incident arc in the shortest path DAG assert map_vpreds == dict() # Every target are at infinite distance excepted the source node. assert map_vdist == {u: infty if u != s else 0 for u in vertices(g)}
def depth_first_search_graph( g: Graph, pmap_vcolor: ReadWritePropertyMap, vis=DefaultDepthFirstSearchVisitor(), # N.B: The following parameters doe not exists in libboost: if_push=None, # if_push(e :EdgeDecriptor) -> bool returns True iff e is relevant forward=True): for u in vertices(g): if pmap_vcolor[u] == WHITE: depth_first_search(u, g, pmap_vcolor, vis, if_push, forward)
def depth_first_search_graph( g: Graph, sources: set = None, # Or a generator e.g. vertices(g) pmap_vcolor: ReadWritePropertyMap = None, vis: DefaultDepthFirstSearchVisitor = None, if_push: bool = None # if_push(e :EdgeDecriptor) -> bool ): if pmap_vcolor is None: map_vcolor = defaultdict(int) pmap_vcolor = make_assoc_property_map(map_vcolor) for u in (sources if sources else vertices(g)): if pmap_vcolor[u] == WHITE: depth_first_search(u, g, pmap_vcolor, vis, if_push)
def dijkstra_shortest_paths_initialization(g: DirectedGraph, s: int, pmap_vcolor: ReadWritePropertyMap, pmap_vdist: ReadWritePropertyMap, zero: int, infty: int, vis: DijkstraVisitor = None): if vis is None: vis = DijkstraVisitor() # WHITE: not yet processed, GRAY: under process, BLACK: processed. pmap_vcolor[s] = WHITE for u in vertices(g): pmap_vdist[u] = zero if u == s else infty vis.initialize_vertex(u, g)
def strong_components(g: DirectedGraph, pmap_component: ReadWritePropertyMap) -> int: map_vcolor = defaultdict(int) map_root = defaultdict(int) map_discover_time = defaultdict(int) pmap_vcolor = make_assoc_property_map(map_vcolor) pmap_root = make_assoc_property_map(map_root) pmap_discover_time = make_assoc_property_map(map_discover_time) stack = deque() vis = TarjanVisitor(pmap_component, pmap_root, pmap_discover_time, stack) depth_first_search_graph(g, vertices(g), pmap_vcolor, vis, None) return vis.total
def make_gdp2() -> GraphDp: g = make_g() vlabel = {u : "v%s" % u for u in vertices(g)} elabel = {e : "e%s%s" % (source(e, g), target(e, g)) for e in edges(g)} gdp = GraphDp( g, dpv = { "label" : make_assoc_property_map(vlabel), "color" : make_func_property_map(lambda q: "red" if q % 2 else "green"), }, dpe = { "label" : make_assoc_property_map(elabel), "color" : make_func_property_map(lambda e: "red" if target(e, g) % 2 else "green"), } ) return gdp
def test_strong_components(): # Create the graph g = DirectedGraph(7) add_edge(0, 1, g) add_edge(1, 2, g) add_edge(2, 3, g) add_edge(3, 1, g) add_edge(3, 4, g) add_edge(4, 5, g) add_edge(5, 6, g) add_edge(6, 4, g) # Find strong connected components map_component = {u : None for u in vertices(g)} pmap_component = make_assoc_property_map(map_component) strong_components(g, pmap_component) # Rendering pmap_color = make_assoc_property_map({ 0 : "red", 1 : "blue", 2 : "green", 3 : "purple" }) assert map_component == { 0 : 2, 1 : 1, 2 : 1, 3 : 1, 4 : 0, 5 : 0, 6 : 0, } if in_ipynb(): html(strong_components_to_html(g, pmap_color, pmap_component).replace("\\n", ""))
def check_pmap_vertex(pmap_expected: ReadPropertyMap, pmap_obtained: ReadPropertyMap, g: Graph, pmap_name: str = ""): check_pmap(pmap_expected, pmap_obtained, vertices(g), pmap_name)
def dijkstra_shortest_paths(g: DirectedGraph, s: int, pmap_eweight: ReadPropertyMap, pmap_vpreds: ReadWritePropertyMap, pmap_vdist: ReadWritePropertyMap, compare: BinaryPredicate = Less(), combine: BinaryFunction = ClosedPlus(), zero: int = 0, infty: int = sys.maxsize, vis: DijkstraVisitor = DijkstraVisitor()): """ Compute the shortest path in a graph from a given source node. Args: g: A DirectedGraph instance. s: The vertex descriptor of the source node. pmap_eweight: A ReadPropertyMap{EdgeDescriptor : Distance} which map each edge with its weight. pmap_vpreds: A ReadWritePropertyMap{VertexDescriptor : EdgeDescriptor} which will map each vertex with its incident arcs in the shortest path Directed Acyclic Graph. pmap_vdist: A ReadWritePropertyMap{VertexDescriptor : Distance} which will map each vertex with the weight of its shortest path(s) from s. zero: The null Distance (e.g. 0). infty: The infinite Distance (e.g. sys.maxsize). vis: A DijkstraVisitor instance. Example: g = DirectedGraph(2) e, _ = add_edge(0, 1, g) map_eweight[e] = 10 map_vpreds = defaultdict(set) map_vdist = dict() dijkstra_shortest_paths( g, u, make_assoc_property_map(map_eweight), make_assoc_property_map(map_vpreds), make_assoc_property_map(map_vdist) ) """ # WHITE: not yet processed, GRAY: under process, BLACK: processed. color = defaultdict(int) pmap_vcolor = make_assoc_property_map(color) pmap_vcolor[s] = WHITE for u in vertices(g): pmap_vdist[u] = zero if u == s else infty #pmap_vpreds[u] = set() #pmap_vcolor[u] = GRAY if u == s else WHITE stack = {s} while stack: u = min(stack, key=lambda u: pmap_vdist[u]) # TODO use compare stack.remove(u) w_su = pmap_vdist[u] # Update weight and predecessors of each successor of u for e in out_edges(u, g): v = target(e, g) w_sv = pmap_vdist[v] w_uv = pmap_eweight[e] w = combine(w_su, w_uv) if compare(w, w_sv): # Traversing u is worth! pmap_vdist[v] = w pmap_vpreds[v] = {e} if pmap_vcolor[v] == WHITE: pmap_vcolor[v] = GRAY stack.add(v) elif w == w_sv: # Hence we discover equally-cost shortest paths preds_v = pmap_vpreds[v] preds_v.add(e) pmap_vpreds[v] = preds_v pmap_vcolor[u] = BLACK