Example #1
0
def mst_kruskal(graph):
    # Kruskal's algorithm explanation https://www.youtube.com/watch?v=71UQH7Pr9kU
    mst = Graph(False)
    min_edge_heap = [
    ]  # use as priority queue to select and edge with minimum weight

    # 1. Sort the edges in ascending order of weights
    for edge in graph.get_edges():
        heapq.heappush(min_edge_heap, edge)

    input_graph_num_vertices = len(graph.get_vertices())
    # 2. Keep adding edges until MST will reach all vertices
    while (len(min_edge_heap) > 0) and (len(mst.get_vertices()) <
                                        input_graph_num_vertices):
        # 3. Select an edge with minimum weight (greedy algorithm)
        min_edge = heapq.heappop(min_edge_heap)
        start_vertex = min_edge.get_start_vertex()
        end_vertex = min_edge.get_end_vertex()

        # 4. Add edge in MST and check if it form a cycle then remove edge, otherwise leave it in MST
        mst.add_vertex(start_vertex.get_label())
        mst.add_vertex(end_vertex.get_label())

        start_label = start_vertex.get_label()
        end_label = end_vertex.get_label()
        weight = min_edge.get_weight()
        mst.add_edge(start_label, end_label, weight)

        if has_cycle(mst):
            mst.remove_edge(start_label, end_label, weight)

    return mst
def mst_prim(graph):
    # Prim's algorithm explanation https://www.youtube.com/watch?v=cplfcGZmX7I
    # This algorithm return list of edges, so if we have edges we may recreate MST
    mst = Graph(False)
    min_edge_heap = []
    visited_vertices = set()

    # 1. Choose arbitary vertex from which MST algorithm start looking for edges
    arbitary_vertex = next(iter(graph.get_vertices()))
    visited_vertices.add(arbitary_vertex)
    mst.add_vertex(arbitary_vertex)

    # 2. Find all adjacent edges of arbitary vertex and add them to heap
    for edge in graph.get_vertex(arbitary_vertex).get_outbound_edges():
        heapq.heappush(min_edge_heap, edge)

    input_graph_num_vertices = len(graph.get_vertices())
    while len(mst.get_vertices()) < input_graph_num_vertices:
        # 3. Select an edge with minimum weight (greedy algorithm)
        while True:
            min_edge = heapq.heappop(min_edge_heap)
            min_vertex = min_edge.get_end_vertex()
            min_vertex_label = min_vertex.get_label()
            if min_vertex_label not in visited_vertices:
                break

        # 4. Mark selected vertex as visited and add selected edge to MST
        visited_vertices.add(min_vertex_label)
        mst.add_vertex(min_vertex_label)
        mst.add_edge(min_edge.get_start_vertex().get_label(),
                     min_edge.get_end_vertex().get_label(), min_edge.get_weight())

        # 4. Find all adjacent edges of min vertex and add them to heap
        for edge in min_vertex.get_outbound_edges():
            heapq.heappush(min_edge_heap, edge)

    return mst