Exemple #1
0
def graph_extract(s: int,
                  g: Graph,
                  pmap_vrelevant=None,
                  pmap_erelevant=None,
                  callback_vertex_extract=None,
                  callback_edge_extract=None):
    """
    Extract the edges of a given Graph according to an edge-based filtering starting
    from a given source node.
    Args:
        s: The VertexDescriptor of the source node.
        g: A Graph instance.
        pmap_vrelevant: A ReadPropertyMap{VertexDescriptor : bool} which indicates
            for each vertex whether if it must be duped or not.
        pmap_erelevant: A ReadPropertyMap{EdgeDescriptor : bool} which indicates
            each edge of the Graph with a boolean equal to True iff the edge is relevant.
        callback_vertex_extract:
        callback_edge_extract:
    """
    if not pmap_vrelevant:
        pmap_vrelevant = make_func_property_map(lambda u: True)
    if not pmap_erelevant:
        pmap_erelevant = make_func_property_map(lambda e: True)

    map_vcolor = defaultdict(int)
    pmap_vcolor = make_assoc_property_map(map_vcolor)
    vis = DepthFirstSearchExtractVisitor(pmap_vrelevant, pmap_erelevant,
                                         pmap_vcolor, callback_vertex_extract,
                                         callback_edge_extract)
    depth_first_search(s,
                       g,
                       pmap_vcolor,
                       vis,
                       if_push=lambda e, g: pmap_erelevant[e] and
                       pmap_vrelevant[target(e, g)])
Exemple #2
0
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
Exemple #3
0
def graph_copy(s: int,
               g: Graph,
               g_dup: Graph,
               pmap_vrelevant: ReadPropertyMap = None,
               pmap_erelevant: ReadPropertyMap = None,
               pmap_vertices: ReadWritePropertyMap = None,
               pmap_edges: ReadWritePropertyMap = None,
               callback_dup_vertex=None,
               callback_dup_edge=None):
    """
    Copy a sub-graph from a Graph according to an edge-based filtering
    starting from a given source node.
    Args:
        s: The VertexDescriptor of the source node.
        g: A Graph instance.
        pmap_vrelevant: A ReadPropertyMap{VertexDescriptor : bool} which indicates
            for each vertex whether if it must be duped or not.
            Only used if vis == None.
        pmap_erelevant: A ReadPropertyMap{EdgeDescriptor : bool} which indicates
            for each edge whether if it must be duped or not.
            Only used if vis == None.
        callback_dup_vertex: Callback(u, g, u_dup, g_dup).
            Pass None if irrelevant.
        callback_dup_edge: Callback(e, g, e_dup, g_dup).
            Pass None if irrelevant.
        vis: Pass a custom DepthFirstSearchExtractVisitor or None.
            This visitor must overload super()'s methods.
    """
    # Prepare the needed mappings.
    map_vcolor = defaultdict(int)
    pmap_vcolor = make_assoc_property_map(map_vcolor)

    if not pmap_vrelevant:
        pmap_vrelevant = make_func_property_map(lambda u: True)
    if not pmap_erelevant:
        pmap_erelevant = make_func_property_map(lambda e: True)

    # Prepare the DepthFirstSearchCopyVisitor.
    if not pmap_vertices:
        map_vertices = dict()
        pmap_vertices = make_assoc_property_map(map_vertices)
    if not pmap_edges:
        map_edges = dict()
        pmap_edges = make_assoc_property_map(map_edges)

    vis = DepthFirstSearchCopyVisitor(g_dup, pmap_vrelevant, pmap_erelevant,
                                      pmap_vertices, pmap_edges, pmap_vcolor,
                                      callback_dup_vertex, callback_dup_edge)

    # Copy g to g_copy according to pmap_erelevant using a DFS from s.
    depth_first_search(s,
                       g,
                       pmap_vcolor,
                       vis,
                       if_push=lambda e, g: pmap_erelevant[e] and
                       pmap_vrelevant[target(e, g)])
Exemple #4
0
def cut(s: int, g: Graph, in_cut) -> set:
    """
    Find a vertex cut given an edge cut.
    Args:
        g: A `Graph` instance corresponding to an acyclic graph.
        s: The `VertexDescriptor` corresponding to the source vertex.
        in_cut: `Callback(EdgeDescriptor, Graph) -> bool` indicating whether an
            edge belong to the considered cut.
    """
    class LeavesVisitor(DefaultDepthFirstSearchVisitor):
        def __init__(self, leaves: set):
            self.leaves = leaves

        def examine_edge(self, e: EdgeDescriptor, g: Graph):
            u = source(e, g)
            self.leaves.discard(u)

        def discover_vertex(self, u: int, g: Graph):
            self.leaves.add(u)

    class IfPush:
        def __init__(self, in_cut, cutting_edges: set):
            self.in_cut = in_cut
            self.cutting_edges = cutting_edges

        def __call__(self, e: EdgeDescriptor, g: Graph) -> bool:
            is_cutting_edge = self.in_cut(e, g)
            if is_cutting_edge:
                self.cutting_edges.add(e)
            return not is_cutting_edge

    leaves = set()
    cutting_edges = set()
    map_vcolor = defaultdict(int)
    depth_first_search(s,
                       g,
                       pmap_vcolor=make_assoc_property_map(map_vcolor),
                       vis=LeavesVisitor(leaves),
                       if_push=IfPush(in_cut, cutting_edges))
    return {target(e, g)
            for e in cutting_edges
            } | {u
                 for u in leaves} - {source(e, g)
                                     for e in cutting_edges}