Given a connected, undirected weighted graph G = (V, E), we want to find a spanning tree of G with the minimal sum of edge weights.
A spanning tree connects all vertices without any cycles and uses the minimum possible edges: |V| - 1.
Imagine cities (nodes) in Europe connected via train tracks (edges with weights = cost). We want every city connected with minimal total track cost, without loops.
# Prim's Algorithm
import heapq # heapq is Python's min-priority queue implementation, we could do it without and use a for-loop to find the min cost edge
def prim(graph, start):
mst = set() # Set to store edges (from, to, cost) of the MST
visited = set([start]) # Set of vertices already included in MST
# Edges list will act as a min-priority queue.
# Stores tuples of (cost, from_node, to_node)
# Initialize with edges from the starting node
edges = []
for to_node, cost in graph[start]:
heapq.heappush(edges, (cost, start, to_node))
while edges and len(mst) < len(graph) - 1:
cost, frm, to = heapq.heappop(edges) # Get the smallest edge
if to not in visited:
visited.add(to)
mst.add((frm, to, cost)) # Add edge to MST
# Add new candidate edges from the newly added 'to' node
for to_next, cost_next in graph[to]:
if to_next not in visited:
heapq.heappush(edges, (cost_next, to, to_next))
return mst