def make_graph_2():
    # https://www.youtube.com/watch?v=-mOEd_3gTK0&ab_channel=TusharRoy-CodingMadeSimple
    graph = AdjacencyList(5)
    zero = graph.add_vertex(index=0, rep='(0)')
    one = graph.add_vertex(index=1, rep='(1)')
    two = graph.add_vertex(index=2, rep='(2)')
    three = graph.add_vertex(index=3, rep='(3)')
    four = graph.add_vertex(index=4, rep='(4)')
    graph.add_edge(origin_vertex=zero, destination_vertex=one, weight=4)
    graph.add_edge(origin_vertex=zero, destination_vertex=two, weight=5)
    graph.add_edge(origin_vertex=one, destination_vertex=two, weight=-3)
    graph.add_edge(origin_vertex=zero, destination_vertex=three, weight=8)
    graph.add_edge(origin_vertex=three, destination_vertex=four, weight=2)
    graph.add_edge(origin_vertex=four, destination_vertex=three, weight=1)
    graph.add_edge(origin_vertex=two, destination_vertex=four, weight=4)
    expected = [0, 4, 1, 6, 5]
    return graph, zero, three, expected
def make_graph_with_neg_cycle():
    # https://www.youtube.com/watch?v=-mOEd_3gTK0&t=969s&ab_channel=TusharRoy-CodingMadeSimple
    graph = AdjacencyList(4)
    zero = graph.add_vertex(index=0, rep='(0)')
    one = graph.add_vertex(index=1, rep='(1)')
    two = graph.add_vertex(index=2, rep='(2)')
    three = graph.add_vertex(index=3, rep='(3)')
    graph.add_edge(origin_vertex=zero, destination_vertex=one, weight=1)
    graph.add_edge(origin_vertex=one, destination_vertex=two, weight=3)
    graph.add_edge(origin_vertex=two, destination_vertex=three, weight=2)
    graph.add_edge(origin_vertex=three, destination_vertex=one, weight=-6)
    expected = False
    return graph, zero, one, expected
def make_graph_1():
    # https://www.youtube.com/watch?v=4OQeCuLYj-4&ab_channel=MichaelSambol
    graph = AdjacencyList(4)
    one = graph.add_vertex(index=0, rep='(1)')
    two = graph.add_vertex(index=1, rep='(2)')
    three = graph.add_vertex(index=2, rep='(3)')
    four = graph.add_vertex(index=3, rep='(4)')
    graph.add_edge(origin_vertex=one, destination_vertex=three, weight=-2)
    graph.add_edge(origin_vertex=three, destination_vertex=four, weight=2)
    graph.add_edge(origin_vertex=four, destination_vertex=two, weight=-1)
    graph.add_edge(origin_vertex=two, destination_vertex=three, weight=3)
    graph.add_edge(origin_vertex=two, destination_vertex=one, weight=4)
    return graph, four, three
def make_graph_1():
    # http://www.programming-algorithms.net/article/47389/Bellman-Ford-algorithm
    graph = AdjacencyList(6)
    S = graph.add_vertex(index=0, rep='S')
    A = graph.add_vertex(index=1, rep='A')
    B = graph.add_vertex(index=2, rep='B')
    C = graph.add_vertex(index=3, rep='C')
    D = graph.add_vertex(index=4, rep='D')
    E = graph.add_vertex(index=5, rep='E')
    graph.add_edge(origin_vertex=S, destination_vertex=A, weight=10)
    graph.add_edge(origin_vertex=S, destination_vertex=E, weight=8)
    graph.add_edge(origin_vertex=E, destination_vertex=D, weight=1)
    graph.add_edge(origin_vertex=D, destination_vertex=A, weight=-4)
    graph.add_edge(origin_vertex=D, destination_vertex=C, weight=-1)
    graph.add_edge(origin_vertex=A, destination_vertex=C, weight=2)
    graph.add_edge(origin_vertex=C, destination_vertex=B, weight=-2)
    graph.add_edge(origin_vertex=B, destination_vertex=A, weight=1)
    # S A B C D E
    # 0 5 5 7 9 8
    expected = [0, 5, 5, 7, 9, 8]
    return graph, S, C, expected
Exemplo n.º 5
0
def make_networks_codeforces():
    flow_network = AdjacencyList(4)
    one = flow_network.add_vertex(index=0, rep='(1)')
    two = flow_network.add_vertex(index=1, rep='(2)')
    three = flow_network.add_vertex(index=2, rep='(3)')
    four = flow_network.add_vertex(index=3, rep='(4)')
    flow_network.add_edge(origin_vertex=one,
                          destination_vertex=two,
                          capacity=10,
                          flow=0)
    flow_network.add_edge(origin_vertex=one,
                          destination_vertex=three,
                          capacity=10,
                          flow=0)
    flow_network.add_edge(origin_vertex=two,
                          destination_vertex=three,
                          capacity=1,
                          flow=0)
    flow_network.add_edge(origin_vertex=two,
                          destination_vertex=four,
                          capacity=10,
                          flow=0)
    flow_network.add_edge(origin_vertex=three,
                          destination_vertex=four,
                          capacity=10,
                          flow=0)

    residual_network = AdjacencyList(4)
    one_r = residual_network.add_vertex(index=0, rep='(1)')
    two_r = residual_network.add_vertex(index=1, rep='(2)')
    three_r = residual_network.add_vertex(index=2, rep='(3)')
    four_r = residual_network.add_vertex(index=3, rep='(4)')
    residual_network.add_edge(origin_vertex=one_r,
                              destination_vertex=two_r,
                              residual_capacity=10,
                              flow=0)
    residual_network.add_edge(origin_vertex=one_r,
                              destination_vertex=three_r,
                              residual_capacity=10,
                              flow=0)
    residual_network.add_edge(origin_vertex=two_r,
                              destination_vertex=three_r,
                              residual_capacity=1,
                              flow=0)
    residual_network.add_edge(origin_vertex=two_r,
                              destination_vertex=four_r,
                              residual_capacity=10,
                              flow=0)
    residual_network.add_edge(origin_vertex=three_r,
                              destination_vertex=four_r,
                              residual_capacity=10,
                              flow=0)

    return flow_network, residual_network, one, four, one_r, four_r
Exemplo n.º 6
0
def make_networks_mathspace():
    # https://mathspace.co/learn/world-of-maths/networks/network-flow-18724/network-flow-1289/
    flow_network = AdjacencyList(4)
    A = flow_network.add_vertex(index=0, rep='A')
    B = flow_network.add_vertex(index=1, rep='B')
    D = flow_network.add_vertex(index=2, rep='D')
    C = flow_network.add_vertex(index=3, rep='C')
    flow_network.add_edge(origin_vertex=A,
                          destination_vertex=B,
                          capacity=12,
                          flow=0)
    flow_network.add_edge(origin_vertex=A,
                          destination_vertex=D,
                          capacity=9,
                          flow=0)
    flow_network.add_edge(origin_vertex=D,
                          destination_vertex=B,
                          capacity=8,
                          flow=0)
    flow_network.add_edge(origin_vertex=B,
                          destination_vertex=C,
                          capacity=15,
                          flow=0)
    flow_network.add_edge(origin_vertex=D,
                          destination_vertex=C,
                          capacity=11,
                          flow=0)

    residual_network = AdjacencyList(4)
    Ar = residual_network.add_vertex(index=0, rep='A')
    Br = residual_network.add_vertex(index=1, rep='B')
    Dr = residual_network.add_vertex(index=2, rep='D')
    Cr = residual_network.add_vertex(index=3, rep='C')
    residual_network.add_edge(origin_vertex=Ar,
                              destination_vertex=Br,
                              residual_capacity=12,
                              flow=0)
    residual_network.add_edge(origin_vertex=Ar,
                              destination_vertex=Dr,
                              residual_capacity=9,
                              flow=0)
    residual_network.add_edge(origin_vertex=Dr,
                              destination_vertex=Br,
                              residual_capacity=8,
                              flow=0)
    residual_network.add_edge(origin_vertex=Br,
                              destination_vertex=Cr,
                              residual_capacity=15,
                              flow=0)
    residual_network.add_edge(origin_vertex=Dr,
                              destination_vertex=Cr,
                              residual_capacity=11,
                              flow=0)
    return flow_network, residual_network, A, C, Ar, Cr
Exemplo n.º 7
0
def make_networks():
    # Modeling 2nd graph from with max flow of 17: https://www.hackerearth.com/practice/algorithms/graphs/maximum-flow/tutorial/
    flow_network = AdjacencyList(6)
    S = flow_network.add_vertex(index=0, rep='S')
    A = flow_network.add_vertex(index=1, rep='A')
    B = flow_network.add_vertex(index=2, rep='B')
    C = flow_network.add_vertex(index=3, rep='C')
    D = flow_network.add_vertex(index=4, rep='D')
    T = flow_network.add_vertex(index=5, rep='T')
    # Set all flows to 0.
    SA = flow_network.add_edge(origin_vertex=S,
                               destination_vertex=A,
                               capacity=10,
                               flow=0)
    AC = flow_network.add_edge(origin_vertex=A,
                               destination_vertex=C,
                               capacity=8,
                               flow=0)
    CT = flow_network.add_edge(origin_vertex=C,
                               destination_vertex=T,
                               capacity=10,
                               flow=0)
    AB = flow_network.add_edge(origin_vertex=A,
                               destination_vertex=B,
                               capacity=2,
                               flow=0)
    SB = flow_network.add_edge(origin_vertex=S,
                               destination_vertex=B,
                               capacity=8,
                               flow=0)
    BC = flow_network.add_edge(origin_vertex=B,
                               destination_vertex=C,
                               capacity=6,
                               flow=0)
    BD = flow_network.add_edge(origin_vertex=B,
                               destination_vertex=D,
                               capacity=7,
                               flow=0)
    DT = flow_network.add_edge(origin_vertex=D,
                               destination_vertex=T,
                               capacity=10,
                               flow=0)

    # Make residual graph.
    residual_network = AdjacencyList(6)
    Sr = residual_network.add_vertex(index=0, rep='S')
    Ar = residual_network.add_vertex(index=1, rep='A')
    Br = residual_network.add_vertex(index=2, rep='B')
    Cr = residual_network.add_vertex(index=3, rep='C')
    Dr = residual_network.add_vertex(index=4, rep='D')
    Tr = residual_network.add_vertex(index=5, rep='T')
    # All edges have residual capacity = capacity of edge - flow, all flow is 0 to start.
    SAr = residual_network.add_edge(origin_vertex=Sr,
                                    destination_vertex=Ar,
                                    residual_capacity=10,
                                    flow=0)
    ACr = residual_network.add_edge(origin_vertex=Ar,
                                    destination_vertex=Cr,
                                    residual_capacity=8,
                                    flow=0)
    CTr = residual_network.add_edge(origin_vertex=Cr,
                                    destination_vertex=Tr,
                                    residual_capacity=10,
                                    flow=0)
    ABr = residual_network.add_edge(origin_vertex=Ar,
                                    destination_vertex=Br,
                                    residual_capacity=2,
                                    flow=0)
    SBr = residual_network.add_edge(origin_vertex=Sr,
                                    destination_vertex=Br,
                                    residual_capacity=8,
                                    flow=0)
    BCr = residual_network.add_edge(origin_vertex=Br,
                                    destination_vertex=Cr,
                                    residual_capacity=6,
                                    flow=0)
    BDr = residual_network.add_edge(origin_vertex=Br,
                                    destination_vertex=Dr,
                                    residual_capacity=7,
                                    flow=0)
    DTr = residual_network.add_edge(origin_vertex=Dr,
                                    destination_vertex=Tr,
                                    residual_capacity=10,
                                    flow=0)
    return flow_network, residual_network, S, T, Sr, Tr
Exemplo n.º 8
0
def make_networks_example():
    # Network based on: https://www.youtube.com/watch?v=rLIR89YyNjg&ab_channel=A%26A
    flow_network = AdjacencyList(6)
    A = flow_network.add_vertex(index=0, rep='A')
    B = flow_network.add_vertex(index=1, rep='B')
    C = flow_network.add_vertex(index=2, rep='C')
    D = flow_network.add_vertex(index=3, rep='D')
    E = flow_network.add_vertex(index=4, rep='E')
    F = flow_network.add_vertex(index=5, rep='F')
    flow_network.add_edge(origin_vertex=A,
                          destination_vertex=B,
                          capacity=16,
                          flow=0)
    flow_network.add_edge(origin_vertex=B,
                          destination_vertex=C,
                          capacity=12,
                          flow=0)
    flow_network.add_edge(origin_vertex=B,
                          destination_vertex=D,
                          capacity=4,
                          flow=0)
    flow_network.add_edge(origin_vertex=A,
                          destination_vertex=D,
                          capacity=5,
                          flow=0)
    flow_network.add_edge(origin_vertex=C,
                          destination_vertex=D,
                          capacity=9,
                          flow=0)
    flow_network.add_edge(origin_vertex=C,
                          destination_vertex=F,
                          capacity=5,
                          flow=0)
    flow_network.add_edge(origin_vertex=D,
                          destination_vertex=E,
                          capacity=20,
                          flow=0)
    flow_network.add_edge(origin_vertex=C,
                          destination_vertex=E,
                          capacity=7,
                          flow=0)
    flow_network.add_edge(origin_vertex=E,
                          destination_vertex=F,
                          capacity=20,
                          flow=0)

    # Residual network:
    residual_network = AdjacencyList(6)
    Ar = residual_network.add_vertex(index=0, rep='A')
    Br = residual_network.add_vertex(index=1, rep='B')
    Cr = residual_network.add_vertex(index=2, rep='C')
    Dr = residual_network.add_vertex(index=3, rep='D')
    Er = residual_network.add_vertex(index=4, rep='E')
    Fr = residual_network.add_vertex(index=5, rep='F')
    residual_network.add_edge(origin_vertex=Ar,
                              destination_vertex=Br,
                              residual_capacity=16,
                              flow=0)
    residual_network.add_edge(origin_vertex=Br,
                              destination_vertex=Cr,
                              residual_capacity=12,
                              flow=0)
    residual_network.add_edge(origin_vertex=Br,
                              destination_vertex=Dr,
                              residual_capacity=4,
                              flow=0)
    residual_network.add_edge(origin_vertex=Ar,
                              destination_vertex=Dr,
                              residual_capacity=5,
                              flow=0)
    residual_network.add_edge(origin_vertex=Cr,
                              destination_vertex=Dr,
                              residual_capacity=9,
                              flow=0)
    residual_network.add_edge(origin_vertex=Cr,
                              destination_vertex=Fr,
                              residual_capacity=5,
                              flow=0)
    residual_network.add_edge(origin_vertex=Dr,
                              destination_vertex=Er,
                              residual_capacity=20,
                              flow=0)
    residual_network.add_edge(origin_vertex=Cr,
                              destination_vertex=Er,
                              residual_capacity=7,
                              flow=0)
    residual_network.add_edge(origin_vertex=Er,
                              destination_vertex=Fr,
                              residual_capacity=20,
                              flow=0)

    return flow_network, residual_network, A, F, Ar, Fr
Exemplo n.º 9
0
def make_networks_basic_test():
    # A simple linear chain network showing that edges S->A and B->T will be restricted by the min flow in an edge in the augmenting path.
    flow_network = AdjacencyList(4)
    S = flow_network.add_vertex(index=0, rep='S')
    A = flow_network.add_vertex(index=1, rep='A')
    B = flow_network.add_vertex(index=2, rep='B')
    T = flow_network.add_vertex(index=3, rep='T')
    flow_network.add_edge(origin_vertex=S,
                          destination_vertex=A,
                          capacity=50,
                          flow=0)
    flow_network.add_edge(origin_vertex=A,
                          destination_vertex=B,
                          capacity=2,
                          flow=0)
    flow_network.add_edge(origin_vertex=B,
                          destination_vertex=T,
                          capacity=50,
                          flow=0)

    residual_network = AdjacencyList(4)
    Sr = residual_network.add_vertex(index=0, rep='S')
    Ar = residual_network.add_vertex(index=1, rep='A')
    Br = residual_network.add_vertex(index=2, rep='B')
    Tr = flow_network.add_vertex(index=3, rep='T')
    residual_network.add_edge(origin_vertex=Sr,
                              destination_vertex=Ar,
                              residual_capacity=50)
    residual_network.add_edge(origin_vertex=Ar,
                              destination_vertex=Br,
                              residual_capacity=2)
    residual_network.add_edge(origin_vertex=Br,
                              destination_vertex=Tr,
                              residual_capacity=50)
    return flow_network, residual_network, S, T, Sr, Tr
    dfs1_rec = depth_first_search_rec_driver(graph_map, source)
    print(
        "DFS on adjacent map, sometimes different order (all correct, check against 4 solns in test()"
    )
    print("DFS on adj_map graph (iterative): " + str(dfs1_itr))
    print("DFS on adj_map graph (recursive): " + str(dfs1_rec))
    """ Note
    due to randomness with {} sometimes we get a different order using a adj map
    however they are all correct orderings by picking arbitrary adjacent nodes
    see the tests below
    """
    print("Testing DSF on map graph.")
    test_dictionary_adj_map_output()

    print("\nTesting DFS on adjacent list")
    graph_list = AdjacencyList(7)
    # set up adj map graph, slightly different set up due to diff underlying structure
    a = graph_list.add_vertex(0, 'A')
    b = graph_list.add_vertex(1, 'B')
    c = graph_list.add_vertex(2, 'C')
    d = graph_list.add_vertex(3, 'D')
    e = graph_list.add_vertex(4, 'E')
    f = graph_list.add_vertex(5, 'F')
    g = graph_list.add_vertex(6, 'G')
    # Add edges both ways.
    graph_list.add_edge(a, b)
    graph_list.add_edge(a, c)
    graph_list.add_edge(a, e)
    graph_list.add_edge(b, f)
    graph_list.add_edge(b, d)
    graph_list.add_edge(c, g)
Exemplo n.º 11
0
    visited = [-1] * len(nodes)
    component_number = 0  # Label each component starting at 0.
    for node in nodes:
        if visited[node.index] == -1:  # Have not visited this node yet.
            visited[node.index] = component_number
            find_connected_component(graph, visited, node, component_number)
            # We have found all components reachable from node so increment component number to
            # find components reachable from another node, it is guaranteed a node can't be in 2 components
            # as otherwise find_connected_component() would have found it.
            component_number += 1
    return component_number, visited

if __name__ == "__main__":
    from algorithms_datastructures.graphs.implementations.adjacency_list import AdjacencyList

    graph = AdjacencyList(4)
    A = graph.add_vertex(0, "A")
    B = graph.add_vertex(1, "B")
    C = graph.add_vertex(2, "C")
    D = graph.add_vertex(3, "D")

    # Graph is just 4 nodes = 4 components.
    num_components, node_components = connected_components(graph)
    print("number of components %s is correct: %s" % (num_components, num_components == 4))
    print("node components: " + str(node_components))

    # Add edge b/w A and B.
    graph.add_edge(origin_vertex=A, destination_vertex=B)
    num_components, node_components = connected_components(graph)
    print("number of components %s is correct: %s" % (num_components, num_components == 3))
    print("node components: " + str(node_components))
Exemplo n.º 12
0
    graph_map.add_edge(A, B)
    graph_map.add_edge(A, C)
    graph_map.add_edge(A, E)
    graph_map.add_edge(B, C)
    graph_map.add_edge(B, F)
    graph_map.add_edge(C, D)
    graph_map.add_edge(E, D)
    graph_map.add_edge(F, D)
    source = A
    bfs_adj_map = breadth_first_search(graph_map, source)
    print("BFS on adj_map graph: " + str(bfs_adj_map))
    # Sometimes the order of the adjacency_map changes (it is still correct, just not alphabetical)
    # this is because there is some randomness with dictionaries.

    print("\nTesting bfs on adjacency list.")
    graph_list = AdjacencyList(6)
    # This Graph List data structure assumes a directed graph
    # set up adj map graph, slightly different set up due to diff underlying structure
    a = graph_list.add_vertex(0, 'A')
    b = graph_list.add_vertex(1, 'B')
    c = graph_list.add_vertex(2, 'C')
    d = graph_list.add_vertex(3, 'D')
    e = graph_list.add_vertex(4, 'E')
    f = graph_list.add_vertex(5, 'F')
    # Undirected.
    graph_list.add_edge(a, b)
    graph_list.add_edge(a, c)
    graph_list.add_edge(a, e)
    graph_list.add_edge(b, c)
    graph_list.add_edge(b, f)
    graph_list.add_edge(c, d)
    stack = deque()

    for node in nodes:  # O(n)
        if visited[node.index] == 0:
            topological_sort_rec(dag, node, visited, stack)
    topological_ordering = []
    while stack:  # O(n)
        topological_ordering.append(stack.pop().rep)
    return topological_ordering


if __name__ == "__main__":
    from algorithms_datastructures.graphs.implementations.adjacency_list import AdjacencyList

    # Graph from https://www.youtube.com/watch?v=ddTC4Zovtbc
    dag = AdjacencyList(8)
    A = dag.add_vertex(0, 'A')
    B = dag.add_vertex(1, 'B')
    C = dag.add_vertex(2, 'C')
    D = dag.add_vertex(3, 'D')
    E = dag.add_vertex(4, 'E')
    F = dag.add_vertex(5, 'F')
    G = dag.add_vertex(6, 'G')
    H = dag.add_vertex(7, 'H')
    dag.add_edge(origin_vertex=A, destination_vertex=C)
    dag.add_edge(origin_vertex=B, destination_vertex=C)
    dag.add_edge(origin_vertex=B, destination_vertex=D)
    dag.add_edge(origin_vertex=C, destination_vertex=E)
    dag.add_edge(origin_vertex=D, destination_vertex=F)
    dag.add_edge(origin_vertex=E, destination_vertex=H)
    dag.add_edge(origin_vertex=E, destination_vertex=F)