Chapter 44: Prim’s Algorithm
Last updated
Last updated
// 複製圖上的所有點
public func copyVertices(from graph: AdjacencyList) {
for vertex in graph.vertices {
adjacencies[vertex] = []
}
} internal func addAvailableEdges(for vertex: Vertex<T>,
in graph: Graph,
check visited: Set<Vertex<T>>,
to priorityQueue: inout PriorityQueue<Edge<T>>) {
// 對於目前的點所有相連的邊
for edge in graph.edges(from: vertex) {
// 若對應的想連的點,之前並未被拜訪過
if !visited.contains(edge.destination) {
// 將此邊加入priorityQueue中
priorityQueue.enqueue(edge)
}
}
} public func produceMinimumSpanningTree(for graph: Graph) -> (cost: Double, mst: Graph) {
var cost = 0.0
let mst = Graph()
var visited: Set<Vertex<T>> = []
var priorityQueue = PriorityQueue<Edge<T>>(sort: {
$0.weight ?? 0.0 < $1.weight ?? 0.0
})
// Copy all the vertices from the original graph to the minimum spanning tree
mst.copyVertices(from: graph)
guard let start = graph.vertices.first else {
return (cost: cost, mst: mst)
}
visited.insert(start)
// Add all potential edges from the start vertex into the priority queue.
addAvailableEdges(for: start, in: graph, check: visited, to: &priorityQueue)
while let smallestEdge = priorityQueue.dequeue() {
let vertex = smallestEdge.destination
// If this vertex has been visited, restart the loop and get the next smallest edge.”
guard !visited.contains(vertex) else {
continue
}
visited.insert(vertex)
cost += smallestEdge.weight ?? 0.0
// Add the smallest edge into the minimum spanning tree you are constructing.
mst.add(.undirected, from: smallestEdge.source, to: smallestEdge.destination, weight: smallestEdge.weight)
// Add the available edges from the current vertex
addAvailableEdges(for: vertex, in: graph, check: visited, to: &priorityQueue)
}
return (cost: cost, mst: mst)
}