def test_parallel_edges():
    # Prepare graph, two parallel edges from 0 to 1
    g = DirectedGraph()
    u = add_vertex(g)
    v = add_vertex(g)
    (e1, added) = add_edge(u, v, g)
    assert added
    (e2, added) = add_edge(u, v, g)
    assert added
    w = 1
    map_eweight = {
        e1: w,
        e2: w,
    }

    # Call Dijkstra
    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))

    # Check
    assert map_vpreds == {
        v: {e1, e2},
    }

    assert map_vdist == {u: 0, v: w}
def make_graph(links: list,
               pmap_eweight: ReadWritePropertyMap,
               directed: bool = True,
               build_reverse_edge=True):
    def add_node(un, g, d):
        u = d.get(un)
        if not u:
            u = add_vertex(g)
            d[un] = u
        return u

    g = DirectedGraph() if directed else UndirectedGraph()
    d = dict()
    for (un, vn, w) in links:
        u = add_node(un, g, d)
        v = add_node(vn, g, d)
        (e, added) = add_edge(u, v, g)
        assert added
        pmap_eweight[e] = w

        if build_reverse_edge:
            (e, added) = add_edge(v, u, g)
            assert added
            pmap_eweight[e] = w
    return g
Пример #3
0
def test_undirected_graph_node_add_edge():
    # Make graph
    g = make_g1()
    assert out_degree(u, g) == 0
    assert num_edges(g) == 0

    # Add e1
    (e1, added1) = add_edge(u, v, g)
    assert added1
    (e, found) = edge(u, v, g)
    assert found
    assert e == e1
    assert out_degree(u, g) == 1
    assert num_edges(g) == 1

    # No arc
    (e, found) = edge(u, w, g)
    assert not found
    assert {e for e in out_edges(u, g)} == {e1}

    # Add e2
    (e2, added2) = add_edge(u, w, g)
    assert added2
    assert {e for e in out_edges(u, g)} == {e1, e2}
    assert out_degree(u, g) == 2
    assert num_edges(g) == 2
Пример #4
0
def make_g2() -> UndirectedGraph:
    g2 = make_g1()
    add_edge(u, v, g2)
    add_edge(u, v, g2)  # parallel edge
    add_edge(u, w, g2)
    add_edge(v, w, g2)
    add_edge(w, w, g2)
    return g2
Пример #5
0
def make_g2(directed: bool) -> Graph:
    g2 = DirectedGraph(4) if directed else UndirectedGraph(4)
    add_edge(0, 1, g2)
    add_edge(1, 2, g2)
    add_edge(1, 3, g2)
    add_edge(3, 0, g2)
    add_edge(3, 2, g2)
    return g2
Пример #6
0
def test_undirected_graph():
    g = UndirectedGraph()

    assert num_vertices(g) == 0
    u = add_vertex(g)
    assert num_vertices(g) == 1
    v = add_vertex(g)
    assert num_vertices(g) == 2
    w = add_vertex(g)
    assert num_vertices(g) == 3

    assert num_edges(g) == 0
    e_uv, _ = add_edge(u, v, g)
    assert num_edges(g) == 1
    e_uv1, _ = add_edge(v, u, g)
    assert num_edges(g) == 2
    e_uw, _ = add_edge(u, w, g)
    assert num_edges(g) == 3
    e_vw, _ = add_edge(v, w, g)
    assert num_edges(g) == 4

    print("Edges = %s" % {e for e in edges(g)})

    print("In-edges(%s) = %s" % (u, {e for e in in_edges(u, g)}))
    assert in_degree(u, g) == 3
    assert in_degree(v, g) == 3
    assert in_degree(
        w, g) == 2, "in_edges(%s) = %s" % (w, {u
                                               for u in in_edges(w, g)})

    print("Out-edges(%s) = %s" % (u, {e for e in out_edges(u, g)}))
    assert out_degree(u, g) == 3
    assert out_degree(v, g) == 3
    assert out_degree(w, g) == 2

    print("Removing %s" % e_uv)
    remove_edge(e_uv, g)
    assert num_edges(g) == 3

    print("Removing %s" % e_uv1)
    remove_edge(e_uv1, g)
    assert num_edges(g) == 2

    print("Removing %s" % v)
    remove_vertex(v, g)
    assert num_vertices(g) == 2

    print("Edges = %s" % {e for e in edges(g)})
    assert num_edges(g) == 1

    print("Out-edges(%s) = %s" % (u, {e for e in out_edges(u, g)}))
    assert out_degree(u, g) == 1
    assert out_degree(w, g) == 1
    assert in_degree(u, g) == 1
    assert in_degree(w, g) == 1
Пример #7
0
def test_cut_diamond():
    g = DirectedGraph(4)
    (e01, _) = add_edge(0, 1, g)
    (e02, _) = add_edge(0, 2, g)
    (e13, _) = add_edge(1, 3, g)
    (e23, _) = add_edge(2, 3, g)

    obtained = cut(0, g, lambda e, g: e in {e01, e02})
    assert obtained == {1, 2}

    obtained = cut(0, g, lambda e, g: e in {e13, e23})
    assert obtained == {3}
Пример #8
0
def test_undirected_graph_add_vertex():
    g = make_g2()
    assert num_vertices(g) == 3
    assert num_edges(g) == 5

    # Add vertex x
    x = add_vertex(g)
    assert num_vertices(g) == 4

    # Add edge (v -> x)
    add_edge(v, x, g)
    assert num_edges(g) == 6
    assert out_degree(v, g) == 4
Пример #9
0
 def make_graph(edges_set: set) -> DirectedGraph:
     g = DirectedGraph()
     n = 0
     for (u, v) in edges_set:
         assert u >= 0
         while n <= u:
             add_vertex(g)
             n += 1
         while n <= v:
             add_vertex(g)
             n += 1
         add_edge(u, v, g)
     return g
Пример #10
0
 def on_operation(self, a, op :Op, u :int, vs :list) -> int:
     """
     Build edges from an operator to its operand in the `self.ast` AST.
     Args:
         a: `str` represening the processed operator.
         op: `Op` specification of `a`.
         u: parent vertex descriptor (operator).
         vs: list of child vertex descriptors (operands).
     Returns:
         The parent vertex descriptor.
     """
     for v in vs:
         add_edge(u, v, self.ast)
     return u
Пример #11
0
def test_cut():
    g = DirectedGraph(3)
    (e01, _) = add_edge(0, 1, g)
    (e12, _) = add_edge(1, 2, g)

    obtained = cut(0, g, lambda e, g: e in {e01})
    assert obtained == {1}

    obtained = cut(0, g, lambda e, g: e in {e12})
    assert obtained == {2}

    obtained = cut(0, g, lambda e, g: False)
    assert obtained == {2}

    obtained = cut(0, g, lambda e, g: True)
    assert obtained == {1}
def test_simple_graph():
    # Prepare graph, just a 0 -> 1 arc
    g = DirectedGraph()
    u = add_vertex(g)
    v = add_vertex(g)
    e, added = add_edge(u, v, g)
    assert added
    w = 1
    map_eweight = {
        e: w,
    }

    # Call Dijkstra
    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))

    # Check
    assert map_vpreds == {
        v: {e},
    }

    assert map_vdist == {u: 0, v: w}
Пример #13
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))
Пример #14
0
 def examine_relevant_edge(self, e: EdgeDescriptor, g: Graph):
     u = source(e, g)
     v = target(e, g)
     u_dup = self.m_pmap_vertices[u]
     v_dup = self.m_pmap_vertices[
         v] if v in self.m_dup_vertices else self.dup_vertex(v, g)
     (e_dup, _) = add_edge(u_dup, v_dup, self.m_g_dup)
     if self.m_pmap_edges:
         self.m_pmap_edges[e] = e_dup
     if self.m_callback_dup_edge:
         self.m_callback_dup_edge(e, g, e_dup, self.m_g_dup)
Пример #15
0
    def on_edge(self, line: str, u_alias: int, v_alias: int,
                opts: str) -> EdgeDescriptor:
        u = self.m_aliases[u_alias]
        v = self.m_aliases[v_alias]
        (e, added) = add_edge(u, v, self.m_g)
        assert added

        if self.on_install_edge_property:
            l = re.findall("\\w+=[^\\s]+", opts)  # CRAPPY split
            for opt in l:
                key, value = opt.split("=")
                key = key.strip().strip(",")
                value = value.strip().strip(",")
                self.on_install_edge_property(e, self.m_g, key, value)
        return e
Пример #16
0
def test_cut_tree():
    g = DirectedGraph(9)
    (e01, _) = add_edge(0, 1, g)
    (e02, _) = add_edge(0, 2, g)
    (e23, _) = add_edge(2, 3, g)
    (e24, _) = add_edge(2, 4, g)

    (e35, _) = add_edge(3, 5, g)
    (e36, _) = add_edge(3, 6, g)
    (e45, _) = add_edge(4, 7, g)
    (e46, _) = add_edge(4, 8, g)
    (e19, _) = add_edge(1, 9, g)

    obtained = cut(0, g, lambda e, g: e in {e01, e02})
    assert obtained == {1, 2}

    obtained = cut(0, g, lambda e, g: False)
    assert obtained == {5, 6, 7, 8, 9}

    obtained = cut(0, g, lambda e, g: e in {e01, e23, e24})
    assert obtained == {1, 3, 4}

    obtained = cut(0, g, lambda e, g: e in {e23, e24})
    assert obtained == {3, 4, 9}
Пример #17
0
def make_binary_tree(n=10):
    g = DirectedGraph(n)
    for u in range(n - 1):
        add_edge(int(u / 2), u + 1, g)
    return g
Пример #18
0
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", ""))
Пример #19
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))
Пример #20
0
def make_g() -> DirectedGraph:
    g = DirectedGraph(3)
    e01, _ = add_edge(0, 1, g)
    e12, _ = add_edge(1, 2, g)
    e02, _ = add_edge(0, 2, g)
    return g
Пример #21
0
def make_g1(directed: bool) -> Graph:
    g1 = DirectedGraph(7) if directed else UndirectedGraph(7)
    add_edge(0, 1, g1)
    add_edge(1, 2, g1)
    add_edge(2, 3, g1)
    add_edge(3, 1, g1)
    add_edge(3, 4, g1)
    add_edge(4, 5, g1)
    add_edge(5, 6, g1)
    add_edge(6, 4, g1)
    return g1
Пример #22
0
def test_topological_sort():
    g = DirectedGraph(6)
    for (u, v) in [(0, 1), (2, 4), (2, 5), (0, 3), (1, 4), (4, 3)]:
        add_edge(u, v, g)
    l = topological_sort(g)
    assert list(l) == [2, 5, 0, 1, 4, 3]