Пример #1
0
def topological_sort_kahn(graph: Graph) -> list:
    """
    Ex 22.4-5. If return list is shorter than graph vertex length, it means the topological sort cannot be performed.
    O(V + E) time.
    """
    in_degrees = {}
    ret = []
    for v_key in graph.vertex_keys():
        in_degrees[v_key] = 0
    for u_key in graph.vertex_keys():
        for v_key, _ in graph.get_vertex(u_key).successors():
            in_degrees[v_key] += 1

    zero_in_degree_set = deque()
    for v_key in graph.vertex_keys():
        if in_degrees[v_key] == 0:
            zero_in_degree_set.append(v_key)

    while zero_in_degree_set:
        u_key = zero_in_degree_set.popleft()
        ret.append(u_key)
        for v_key, _ in list(graph.get_vertex(u_key).successors()):
            graph.remove_edge(u_key, v_key)
            in_degrees[v_key] -= 1
            if in_degrees[v_key] == 0:
                zero_in_degree_set.append(v_key)
    return ret
Пример #2
0
def get_transpose(graph: Graph):
    """Ex 22.1-3."""
    tr = Graph()
    for v in graph.vertex_keys():
        tr.add_vertex(Vertex(v))
    for u in graph.vertex_keys():
        for v, weight in graph.get_vertex(u).successors():
            tr.add_edge(v, u, weight)
    return tr
Пример #3
0
def graph_to_adj_matrix(graph: Graph):
    vertex_count = graph.vertex_len
    adj_matrix = [([0] * vertex_count) for _ in range(vertex_count)]
    for u in graph.vertex_keys():
        for v, _ in graph.get_vertex(u).successors():
            adj_matrix[u][v] = 1
    return adj_matrix
Пример #4
0
def scc_tarjan(graph: Graph) -> List[List]:
    sccs = []
    cache = TarjanCache()
    time = TimeCounter()
    for v_key in graph.vertex_keys():
        if v_key not in cache.discover_times:
            _tarjan_internal(graph, v_key, sccs, cache, time)
    return sccs
Пример #5
0
def euler_tour_undirected(graph: Graph) -> list:
    ret = []
    if graph.vertex_len == 0:
        return ret
    for v_key in graph.vertex_keys():
        ret.append(v_key)
        break
    ret, _ = _euler(graph, ret, 0)
    return ret
Пример #6
0
def bfs(graph: Graph, visit_func: Callable[[Any], bool]=None) -> Tuple[dict, dict]:
    open_set = deque()
    came_from = {}
    depths = {}
    visited = set()   # Gray or black nodes
    if not visit_func:
        def visit_func(_): return True

    for v in graph.vertex_keys():
        if v in visited:
            continue
        _bfs_internal(graph, v, visit_func, open_set, came_from, depths, visited)
    return came_from, depths
Пример #7
0
def dfs(graph: Graph, pre_visit_func: Callable[[Any], bool]=None, post_visit_func: Callable[[Any], bool]=None)\
        -> DFSResult:
    """Ex. 22.3-7"""
    if not pre_visit_func:

        def pre_visit_func(_):
            return True

    if not post_visit_func:

        def post_visit_func(_):
            return True

    result = DFSResult()
    time = TimeCounter()
    for v in graph.vertex_keys():
        if v not in result.discover_times and not dfs_internal(
                graph, v, pre_visit_func, post_visit_func, result, time):
            break
    return result