Пример #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)])
Пример #2
0
 def __and__(self, gv):
     return GraphView(
         self.g,
         make_func_property_map(
             lambda v: self.pmap_vrelevant[v] and gv.pmap_vrelevant[v]),
         make_func_property_map(
             lambda e: self.pmap_erelevant[e] and gv.pmap_erelevant[e]))
Пример #3
0
def test_graph_dp_filter():
    def vertex_filter(u):
        return u < 2

    def edge_filter(e, g, vertex_filter):
        return vertex_filter(source(e, g)) and vertex_filter(target(e, g))

    g = make_g()
    gdp = GraphDp(
        g,
        dv={"color": "red"},
        de={"color": "purple"},
        dpv={
            "fontcolor":
            make_func_property_map(lambda e: "blue" if e % 2 else "green")
        })
    ipynb_display_graph(gdp,
                        vs=(u for u in vertices(g) if vertex_filter(u)),
                        es=(e for e in edges(g)
                            if edge_filter(e, g, vertex_filter)))
    gdp = GraphDp(
        g,
        dv={"color": "red"},
        de={"color": "purple"},
        dpv={
            "fontcolor":
            make_func_property_map(lambda e: "blue" if e % 2 else "green")
        })
Пример #4
0
 def __sub__(self, gv):
     return GraphView(
         self.g,
         make_func_property_map(
             lambda v: self.pmap_vrelevant[v] and not gv.pmap_vrelevant[v]),
         make_func_property_map(
             lambda e: (self.pmap_erelevant[e] and not gv.pmap_erelevant[
                 e] or (not gv.pmap_vrelevant[self.source(e)] and not gv.
                        pmap_vrelevant[self.target(e)]))))
Пример #5
0
 def __init__(self,
              g: DirectedGraph,
              pmap_vrelevant: ReadPropertyMap = None,
              pmap_erelevant: ReadPropertyMap = None):
     self.g = g
     self.pmap_vrelevant = (pmap_vrelevant if pmap_vrelevant else
                            make_func_property_map(lambda u: True))
     self.pmap_erelevant = (pmap_erelevant if pmap_erelevant else
                            make_func_property_map(lambda e: True))
Пример #6
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)])
Пример #7
0
def test_graph_extract_small(threshold :int = 50):
    g = DirectedGraph(5)
    (e01, _) = add_edge(0, 1, g)
    (e02, _) = add_edge(0, 2, g)
    (e04, _) = add_edge(0, 4, g)
    (e12, _) = add_edge(1, 2, g)
    (e23, _) = add_edge(2, 3, g)
    (e24, _) = add_edge(2, 4, g)
    (e40, _) = add_edge(4, 0, g)
    (e44, _) = add_edge(4, 4, g)
    pmap_eweight = make_assoc_property_map({
        e01 : 83,
        e02 : 3,
        e04 : 78,
        e12 : 92,
        e23 : 7,
        e24 : 18,
        e40 : 51,
        e44 : 84,
    })

    extracted_edges = set()
    pmap_erelevant = make_func_property_map(lambda e: pmap_eweight[e] >= threshold)
    graph_extract(
        0, g,
        pmap_erelevant        = pmap_erelevant,
        callback_edge_extract = lambda e, g: extracted_edges.add(e)
    )

    if in_ipynb():
        pmap_extracted = make_func_property_map(lambda e: e in extracted_edges)
        html(dotstr_to_html(GraphDp(
            g,
                dpe = {
                    "color" : make_func_property_map(lambda e : "darkgreen" if pmap_extracted[e] else "lightgrey"),
                    "style" : make_func_property_map(lambda e : "solid"     if pmap_extracted[e] else "dashed"),
                    "label" : pmap_eweight,
                }
            ).to_dot())
        )

    expected_edges = None

    if threshold == 0:
        expected_edges = {e for e in edges(g)}
    elif threshold == 50:
        expected_edges = {e12, e40, e44, e04, e01}
    elif threshold > 100:
        expected_edges = set()

    if expected_edges is not None:
        assert (extracted_edges == expected_edges), """Invalid edges:
            For threshold = %s:
            extracted: %s
            expected:  %s
        """ % (threshold, sorted(extracted_edges), sorted(expected_edges))
Пример #8
0
 def to_dot(self, **kwargs) -> str:
     dpv = {
         "shape":
         make_func_property_map(lambda u: "doublecircle"
                                if self.is_final(u) else "circle"),
         "label":
         make_func_property_map(lambda u: "^"
                                if self.is_initial(u) else self.symbol(u))
     }
     kwargs = enrich_kwargs(dpv, "dpv", **kwargs)
     return super().to_dot(**kwargs)
Пример #9
0
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
Пример #10
0
def make_fda2():
    return make_automaton(
        [
            (0, 1, 'x'), (1, 1, 'y')
        ], 0,
        make_func_property_map(lambda q: q in {1})
    )
Пример #11
0
 def demo_minimal_cover(g: DirectedGraph, min_fds: set):
     if not in_ipynb(): return
     s_dot = GraphDp(
         g,
         dg_default={
             "rankdir": "LR"
         },
         dpe={
             "color":
             make_func_property_map(lambda e: "darkgreen" if edge_to_pair(
                 e, g) in min_fds else "red"),
             "style":
             make_func_property_map(lambda e: "solid" if edge_to_pair(e, g)
                                    in min_fds else "dashed"),
         }).to_dot()
     html(dotstr_to_html(s_dot))
Пример #12
0
def test_incidence_automaton_remove_vertex():
    g = make_incidence_automaton([
            (0, 0, 'a'), (0, 1, 'b'),
            (1, 2, 'a'), (1, 1, 'b'),
            (2, 1, 'a'), (2, 1, 'b'),
            # Add loop and cycles
            (0, 0, 'c'),
            (1, 0, 'c'),
            (2, 2, 'c')
        ], 0, make_func_property_map(lambda q: q in {1})
    )
    assert num_vertices(g) == 3
    assert num_edges(g) == 9

    print("remove_vertex(0)")
    remove_vertex(0, g)
    assert num_vertices(g) == 2
    assert num_edges(g) == 5

    print("remove_vertex(2)")
    remove_vertex(2, g)
    assert num_vertices(g) == 1
    assert num_edges(g) == 1

    print("remove_vertex(1)")
    remove_vertex(1, g)
    assert num_vertices(g) == 0
    assert num_edges(g) == 0
Пример #13
0
def test_dijkstra_shortest_path(links: list = None):
    if links is None:
        links = LINKS
    # Prepare graph
    map_eweight = defaultdict(int)
    pmap_eweight = make_assoc_property_map(map_eweight)
    g = make_graph(links, pmap_eweight, build_reverse_edge=False)

    # Dijkstra, stopped when vertex 9 is reached
    map_vpreds = defaultdict(set)
    map_vdist = defaultdict(int)
    s = 0
    t = 8
    path = dijkstra_shortest_path(g, s, t, pmap_eweight,
                                  make_assoc_property_map(map_vpreds),
                                  make_assoc_property_map(map_vdist))
    if in_ipynb():
        ipynb_display_graph(g,
                            dpe={
                                "color":
                                make_func_property_map(
                                    lambda e: "green" if e in path else "red"),
                                "label":
                                pmap_eweight
                            })
    assert [(source(e, g), target(e, g)) for e in path] == [(0, 5), (5, 6),
                                                            (6, 8)]
Пример #14
0
def make_fda1():
    return make_automaton(
        [
            (0, 1, 'c'), (1, 2, 'a'), (2, 3, 't'),
            (3, 4, 's'), (0, 5, 'b'), (5, 5, 'b'), (5, 2, 'a')
        ], 0,
        make_func_property_map(lambda q: q in {4})
    )
Пример #15
0
def make_gdp2() -> GraphDp:
    g = make_g()
    gdp = GraphDp(
        g,
        dpv={
            "label": make_func_property_map(lambda q: "v{q}"),
            "color":
            make_func_property_map(lambda q: "red" if q % 2 else "green"),
        },
        dpe={
            "label":
            make_func_property_map(lambda e: f"e{source(e, g)}{target(e, g)}"),
            "color":
            make_func_property_map(lambda e: "red"
                                   if target(e, g) % 2 else "green"),
        })
    return gdp
Пример #16
0
 def to_dot(self, **kwargs):
     dpv = {
         "label" : make_func_property_map(
             lambda u: "%s %s" % (u, self.pmap_vlabel[u])
         )
     }
     kwargs = enrich_kwargs(dpv, "dpv", **kwargs)
     return super().to_dot(**kwargs)
Пример #17
0
def strong_components_to_html(g, pmap_color, pmap_component) -> str:
    """
    Args:
        g: A DirectedGraph.
        pmap_component: A ReadPropertyMap, mapping a vertex with its strongly
            connected component.
    """
    return graph_to_html(
        g,
        dpv={
            "color" : make_func_property_map(lambda u: pmap_color[pmap_component[u]])
        },
        dpe={
            "color" : make_func_property_map(lambda e: edge_color(e, g, pmap_component, pmap_color)),
            "style" : make_func_property_map(lambda e: (
                "solid" if edge_color(e, g, pmap_component, pmap_color, None) else "dashed"
            )),
        }
    )
Пример #18
0
def display_graph(g: Graph,
                  pmap_eweight: ReadPropertyMap = None,
                  map_vpreds: dict = None):
    if in_ipynb():
        dpe = dict()
        if pmap_eweight:
            dpe["label"] = pmap_eweight
        if map_vpreds:
            shortest_path_dag = {e for es in map_vpreds.values() for e in es}
            dpe["color"] = make_func_property_map(
                lambda e: "red" if e in shortest_path_dag else None)
        ipynb_display_graph(g, dpe=dpe)
Пример #19
0
def display_strong_components(g, pmap_color, pmap_component) -> str:
    """
    Args:
        g: A DirectedGraph.
        pmap_component: A ReadPropertyMap, mapping a vertex with its strongly
            connected component.
    """
    html = dotstr_to_html(GraphDp(
        g,
        {
            "color" : make_func_property_map(lambda u : pmap_color[pmap_component[u]])
        }, {
            "color" : make_func_property_map(lambda e : edge_color(e, g, pmap_component, pmap_color)),
            "style" : make_func_property_map(lambda e : \
                "solid" if edge_color(e, g, pmap_component, pmap_color, None) else \
                "dashed"
            ),
        }
    ).to_dot())

    return html
Пример #20
0
def test_make_incidence_node_automaton():
    g = make_incidence_node_automaton(
        [(0, 1), (0, 2), (1, 2)],
        q0n=0,
        pmap_vlabel=make_assoc_property_map(
            defaultdict(lambda: None, {
                1: "a",
                2: "b"
            })),
        pmap_vfinal=make_func_property_map(lambda u: u in {0, 2}))
    assert num_vertices(g) == 3
    assert num_edges(g) == 3
    for u in vertices(g):
        assert is_initial(u, g) == (u == 0)
        assert is_final(u, g) == (u in {0, 2})
    assert symbol(0, g) is None
    assert symbol(1, g) == "a"
    assert symbol(2, g) == "b"
Пример #21
0
def make_automaton_from_observation_table(o: ObservationTable,
                                          verbose: bool = False):
    def f(s):
        pass

    log = html if verbose else f
    map_row_state = dict()
    q0 = 0
    final_states = set()
    transitions = list()

    # Build states
    q = 0
    for s in sorted(o.s):  # Hence q0 = 0
        row = o.row(s)
        if row not in map_row_state.keys():
            map_row_state[row] = q
            is_final = o.get(s, "")
            if is_final:
                final_states.add(q)
            log("Adding state %d for prefix %s (row = %s, is_final = %s)" %
                (q, s, o.row(s), is_final))
            q += 1

    # Build transitions
    for (row, q) in map_row_state.items():
        # Find prefix leading to q
        s = None
        for s in o.s:
            if o.row(s) == row: break
        assert s is not None

        for a in o.a:
            r = map_row_state[o.row(s + a)]
            transitions.append((q, r, a))
            log("Adding %s-transition from %d (%s) to %d (%s)" %
                (a, q, o.row(s), r, o.row(s + a)))

    g = make_automaton(transitions, q0,
                       make_func_property_map(lambda q: q in final_states))
    log("final_states = %s" % final_states)
    log("<pre>make_automaton_from_observation_table</pre> returns:")
    log(dotstr_to_html(g.to_dot()))
    return g
Пример #22
0
def test_remove_edge():
    transitions = [
        (0, 0, 'a'),
        (0, 1, 'b'),
        (1, 2, 'a'),
        (1, 1, 'b'),
        (2, 1, 'a'),
        (2, 1, 'b'),
    ]

    g = make_automaton(transitions, 0,
                       make_func_property_map(lambda q: q in {1}))
    n = num_edges(g)
    assert n == 6
    for (u, v, a) in transitions:
        (e, found) = edge(u, v, a, g)
        assert found
        assert source(e, g) == u
        assert target(e, g) == v
        remove_edge(e, g)
        n -= 1
        assert num_edges(g) == n
Пример #23
0
def make_suffix_trie(w :str = "", max_len :int = None, g :Trie = None) -> Trie:
    if g is None:
        g = Trie()
    if num_vertices(g) == 0:
        add_vertex(g)
    g.m_pmap_final = make_func_property_map(lambda q: q != BOTTOM)

    # Naive implementation (slow)
    # g.insert("")
    # for factor in factors(w, max_len):
    #     g.insert(factor)

    # Optimized version, designed by Elie.
    n = len(w)
    for i in range(n):
        q = initial(g)
        for j in range(i, min(n, i + max_len) if max_len else n):
            a = w[j]
            r = delta(q, a, g)
            if r is BOTTOM:
                r = add_vertex(g)
                add_edge(q, r, a, g)
            q = r
    return g
Пример #24
0
def test_remove_edge():
    transitions = [
        (0, 0, 'a'), (0, 1, 'b'),
        (1, 2, 'a'), (1, 1, 'b'),
        (2, 1, 'a'), (2, 1, 'b'),
    ]

    g = make_incidence_automaton(transitions, 0, make_func_property_map(lambda q: q in {1}))
    n = num_edges(g)
    assert n == 6
    for (u, v, a) in transitions:
        (e, found) = edge(u, v, a, g)
        assert found
        assert source(e, g) == u
        assert target(e, g) == v
        du = out_degree(u, g)
        assert isinstance(du, int)
        dv = in_degree(v, g)
        assert isinstance(dv, int)
        remove_edge(e, g)
        assert out_degree(u, g) == du - 1
        assert in_degree(v, g) == dv - 1
        n -= 1
        assert num_edges(g) == n
__license__ = "BSD-3"

from pybgl.automaton import make_automaton
from pybgl.graphviz import dotstr_to_html
from pybgl.property_map import make_func_property_map
from pybgl.html import html
from lstar.automaton_match import automaton_match

G1 = make_automaton([
    (0, 0, 'a'),
    (0, 1, 'b'),
    (1, 2, 'a'),
    (1, 1, 'b'),
    (2, 1, 'a'),
    (2, 1, 'b'),
], 0, make_func_property_map(lambda q: q == 1))

G2 = make_automaton([
    (0, 0, 'a'),
    (0, 1, 'b'),
], 0, make_func_property_map(lambda q: q == 1))

G3 = make_automaton([
    (0, 0, 'a'),
    (0, 1, 'b'),
], 0, make_func_property_map(lambda q: False))

G4 = make_automaton([(0, 0, 'a'), (0, 1, 'b'), (1, 1, 'b'), (1, 0, 'a')], 0,
                    make_func_property_map(lambda q: q == 1))

G5 = make_automaton([(0, 0, 'a'), (0, 1, 'b'), (1, 1, 'b'), (1, 0, 'a')], 0,
Пример #26
0
def test_make_func_property_map():
    pmap_rot13 = make_func_property_map(rot13)
    check_rot13(pmap_rot13)
Пример #27
0
#!/usr/bin/env pytest-3
# -*- coding: utf-8 -*-

__author__ = "Marc-Olivier Buob"
__maintainer__ = "Marc-Olivier Buob"
__email__ = "*****@*****.**"
__copyright__ = "Copyright (C) 2018, Nokia"
__license__ = "BSD-3"

from pybgl.incidence_automaton import (edges, make_incidence_automaton, source,
                                       target, vertices)
from pybgl.prune_incidence_automaton import prune_incidence_automaton
from pybgl.property_map import make_func_property_map

G1 = make_incidence_automaton([(0, 0, 'a'), (0, 1, 'b'), (1, 2, 'a'),
                               (1, 1, 'b'), (2, 1, 'a'), (2, 1, 'b'),
                               (3, 4, 'a'), (5, 1, 'b'), (1, 6, 'a')], 0,
                              make_func_property_map(lambda q: q in {1}))


def test_prune_incidence_automaton():
    assert len(set(edges(G1))) == 8
    prune_incidence_automaton(G1)
    assert set(vertices(G1)) == {0, 1, 2}
    assert set((source(e, G1), target(e, G1)) for e in edges(G1)) == {(0, 1),
                                                                      (1, 2),
                                                                      (0, 0),
                                                                      (2, 1),
                                                                      (1, 1)}
Пример #28
0
def test_graph_to_html_with_pmaps():
    # Configure theme

    GraphvizStyle.set_fg_color("grey")
    GraphvizStyle.set_bg_color("transparent")
    display_graph = ipynb_display_graph

    from pybgl.graph_dp import GraphDp
    from pybgl.property_map import make_func_property_map

    def vertex_filter(u):
        return u < 5

    def edge_filter(e, g, vertex_filter):
        return vertex_filter(source(e, g)) and vertex_filter(target(e, g))

    for G in [DirectedGraph, UndirectedGraph]:
        html(str(G))
        g = make_graph(G)

        # Graph configuration display
        dv = {"color": "purple"}
        de = {"color": "red"}
        dpv = {
            "fontcolor":
            make_func_property_map(lambda e: "cyan" if e % 2 else "orange")
        }
        dpe = {
            "fontcolor":
            make_func_property_map(lambda e: "blue"
                                   if source(e, g) % 2 else "red"),
            "label":
            make_func_property_map(
                lambda e: f"({source(e, g)}, {target(e, g)})")
        }

        # Choose view
        # Omit vs (resp. es) to iterate over all vertices (resp. edges)
        vs = [u for u in vertices(g) if vertex_filter(u)]
        es = [e for e in edges(g) if edge_filter(e, g, vertex_filter)]

        # Method1: call helper (ipynb_display_graph, graph_to_html)
        shtml = graph_to_html(g, dpv=dpv, dpe=dpe, dv=dv, de=de, vs=vs, es=es)
        assert isinstance(shtml, str)
        if in_ipynb():
            ipynb_display_graph(g,
                                dpv=dpv,
                                dpe=dpe,
                                dv=dv,
                                de=de,
                                vs=vs,
                                es=es)

        # Method2: use GraphDp. This offers the opportunity to export the
        # displayed graph to other export formats.
        gdp = GraphDp(g, dpv=dpv, dpe=dpe, dv=dv, de=de)

        # These two commands have the same outcome
        shtml = graph_to_html(gdp, vs=vs, es=es)
        assert isinstance(shtml, str)
        shtml = graph_to_html(gdp,
                              dpv=dpv,
                              dpe=dpe,
                              dv=dv,
                              de=de,
                              vs=vs,
                              es=es)
        assert isinstance(shtml, str)

        if in_ipynb():
            # These two commands have the same outcome
            ipynb_display_graph(gdp, vs=vs, es=es)
            ipynb_display_graph(gdp,
                                dpv=dpv,
                                dpe=dpe,
                                dv=dv,
                                de=de,
                                vs=vs,
                                es=es)
Пример #29
0
def test_graph_copy_small(threshold :int = 50):
    g = DirectedGraph(5)
    (e01, _) = add_edge(0, 1, g)
    (e02, _) = add_edge(0, 2, g)
    (e04, _) = add_edge(0, 4, g)
    (e12, _) = add_edge(1, 2, g)
    (e23, _) = add_edge(2, 3, g)
    (e24, _) = add_edge(2, 4, g)
    (e40, _) = add_edge(4, 0, g)
    (e44, _) = add_edge(4, 4, g)
    map_eweight = {
        e01 : 83,
        e02 : 3,
        e04 : 78,
        e12 : 92,
        e23 : 7,
        e24 : 18,
        e40 : 51,
        e44 : 84,
    }
    pmap_eweight = make_assoc_property_map(map_eweight)
    pmap_erelevant = make_func_property_map(lambda e: pmap_eweight[e] >= threshold)

    g_dup = DirectedGraph(0)

    # Edge duplicate
    map_eweight_dup = dict()
    pmap_eweight_dup = make_assoc_property_map(map_eweight_dup)
    def callback_dup_edge(e, g, e_dup, g_dup):
        pmap_eweight_dup[e_dup] = pmap_eweight[e]

    # Vertex mapping
    map_vertices = dict()
    pmap_vertices = make_assoc_property_map(map_vertices)
    map_edges = dict()
    pmap_edges = make_assoc_property_map(map_edges)

    graph_copy(
        0, g, g_dup,
        pmap_erelevant    = pmap_erelevant,
        pmap_vertices     = pmap_vertices,
        pmap_edges        = pmap_edges,
        callback_dup_edge = callback_dup_edge
    )

    if in_ipynb():
        ori_html = dotstr_to_html(
            GraphDp(
                g,
                dpv = {
                    "label" : make_func_property_map(lambda u: "%s<br/>(becomes %s)" % (u, pmap_vertices[u]))
                },
                dpe = {
                    "color" : make_func_property_map(lambda e : "darkgreen" if pmap_erelevant[e] else "lightgrey"),
                    "style" : make_func_property_map(lambda e : "solid"     if pmap_erelevant[e] else "dashed"),
                    "label" : pmap_eweight,
                }
            ).to_dot()
        )
        dup_html = dotstr_to_html(
            GraphDp(
                g_dup,
                dpe = {
                    "label" : pmap_eweight_dup,
                }
            ).to_dot()
        )
        html(
            """
            <table>
                <tr>
                    <th>Original</th>
                    <th>Extracted</th>
                </tr><tr>
                    <td>%s</td>
                    <td>%s</td>
                </tr>
            </table>
            """ % (ori_html, dup_html)
        )

    if threshold == 50:
        expected_num_edges = 5
        assert map_vertices == {
            0 : 0,
            1 : 1,
            2 : 2,
            4 : 3
        }
        for e, e_dup in map_edges.items():
            u = source(e, g)
            v = target(e, g)
            u_dup = source(e_dup, g_dup)
            v_dup = target(e_dup, g_dup)
            assert u_dup == pmap_vertices[u], "u_dup = %s ; pmap_vertices[%s] = %s" % (u_dup, u, pmap_vertices[u])
            assert v_dup == pmap_vertices[v], "v_dup = %s ; pmap_vertices[%s] = %s" % (v_dup, v, pmap_vertices[v])
            assert pmap_eweight[e] == pmap_eweight_dup[e_dup]
    elif threshold < min([w for w in map_eweight.values()]):
        expected_num_edges = num_edges(g)
    elif threshold > max([w for w in map_eweight.values()]):
        expected_num_edges = 0

    assert expected_num_edges == num_edges(g_dup), \
        """
        Invalid edge number:
          Expected: %s
          Obtained: %s
        """ % (expected_num_edges, num_edges(g_dup))
Пример #30
0
__author__ = "Maxime Raynal"
__maintainer__ = "Maxime Raynal"
__email__ = "*****@*****.**"
__copyright__ = "Copyright (C) 2020, Nokia"
__license__ = "BSD-3"

from pybgl.property_map import make_func_property_map
from pybgl.hopcroft_minimize import hopcroft_minimize
from pybgl.incidence_automaton import make_incidence_automaton, \
    num_vertices, num_edges

G6 = make_incidence_automaton([(0, 1, 'a'), (0, 2, 'b'), (1, 1, 'a'),
                               (1, 3, 'b'), (2, 1, 'a'), (2, 2, 'b'),
                               (3, 1, 'a'), (3, 4, 'b'), (4, 1, 'a'),
                               (4, 2, 'b')], 0,
                              make_func_property_map(lambda q: q in {4}))

G7 = make_incidence_automaton([(0, 1, 'a'), (0, 2, 'b'), (1, 0, 'a'),
                               (1, 3, 'b'), (2, 4, 'a'), (2, 5, 'b'),
                               (3, 4, 'a'), (3, 5, 'b'), (4, 4, 'a'),
                               (4, 5, 'b'), (5, 5, 'a'), (5, 5, 'b')], 0,
                              make_func_property_map(lambda q: q in {2, 3, 4}))

G8 = make_incidence_automaton(
    [(0, 1, 'a'), (1, 2, 'a'), (2, 3, 'a'), (3, 4, 'a'), (4, 5, 'a'),
     (5, 6, 'a'), (6, 7, 'a'), (7, 8, 'a'), (8, 9, 'a'), (9, 10, 'a'),
     (10, 11, 'a'), (11, 12, 'a'), (12, 11, 'a')], 0,
    make_func_property_map(lambda q: q in {0, 2, 4, 6, 8, 10, 12}))

G9 = make_incidence_automaton(
    [(0, 1, 'a'), (1, 2, 'a'), (2, 3, 'a'), (3, 4, 'a'), (4, 5, 'a'),