Beispiel #1
0
def test_strongly_connected_components(graph: DirectedGraph) -> None:
    sccs = graph.strongly_connected_components()
    scc_nodes = list(chain(*sccs))
    nodes = list(graph.nodes())

    assert len(scc_nodes) == len(nodes)
    assert set(scc_nodes) == set(nodes)
Beispiel #2
0
def test_strongly_connected_components_is_deterministic(
        graph: DirectedGraph) -> None:
    assert iequal(
        graph.strongly_connected_components(),
        graph.strongly_connected_components(),
        strict=True,
    )
Beispiel #3
0
def test_topological_sort_is_deterministic(graph: DirectedGraph,
                                           reverse: bool) -> None:
    assert iequal(
        graph.topological_sort(reverse=reverse),
        graph.topological_sort(reverse=reverse),
        strict=True,
    )
Beispiel #4
0
def test_dfs_is_deterministic(graph: DirectedGraph) -> None:
    for node in graph.nodes():
        assert iequal(graph.dfs(node), graph.dfs(node), strict=True)
Beispiel #5
0
def test_topological_sort(graph: DirectedGraph, reverse: bool) -> None:
    sorted_nodes = list(graph.topological_sort(reverse=reverse))
    nodes = list(graph.nodes())

    assert len(sorted_nodes) == len(nodes)
    assert set(sorted_nodes) == set(nodes)
Beispiel #6
0
def graphs(draw,
           directed: bool = True,
           acyclic: bool = False,
           connected: bool = False) -> Graph:
    if directed:
        if connected:
            # TODO
            raise NotImplementedError

        node_pools = draw(lists(nodes(), unique=True))

        if acyclic:
            possible_edges = list(combinations(node_pools, 2))
        else:
            possible_edges = list(permutations(node_pools, 2))

        n = len(possible_edges)
        if n:
            indices = draw(
                lists(integers(min_value=0, max_value=n - 1), unique=True))
        else:
            # Empty or one-noded graph
            indices = []

        edges = [possible_edges[index] for index in indices]

        graph = DirectedGraph()
        for node in node_pools:
            graph.add_node(node)
        for edge in edges:
            graph.add_edge(*edge)

        return graph

    else:
        if acyclic:
            # TODO
            raise NotImplementedError

        if not connected:
            # TODO
            raise NotImplementedError

        node_pools = draw(lists(nodes(), unique=True))

        graph = WeightedGraph()
        if not len(node_pools):
            return graph
        for node in node_pools:
            graph.add_node(node)

        possible_edges = [{n1, n2} for n1, n2 in combinations(node_pools, 2)]

        edges = []
        spanning_tree, not_in_tree = node_pools[:1], node_pools[1:]
        for _ in range(len(node_pools) - 1):
            one_end = draw(sampled_from(spanning_tree))
            the_other_end = draw(sampled_from(not_in_tree))
            edge = {one_end, the_other_end}
            edges.append(edge)
            possible_edges.remove(edge)
            spanning_tree.append(the_other_end)
            not_in_tree.remove(the_other_end)

        n = len(possible_edges)
        if n:
            indices = draw(
                lists(integers(min_value=0, max_value=n - 1), unique=True))
        else:
            indices = []
        edges.extend(possible_edges[index] for index in indices)

        for edge in edges:
            weight = draw(floats())
            graph.add_edge(*edge, weight)

        return graph