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)
def test_strongly_connected_components_is_deterministic( graph: DirectedGraph) -> None: assert iequal( graph.strongly_connected_components(), graph.strongly_connected_components(), strict=True, )
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, )
def test_dfs_is_deterministic(graph: DirectedGraph) -> None: for node in graph.nodes(): assert iequal(graph.dfs(node), graph.dfs(node), strict=True)
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)
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