Skip to content

Commit 4f94036

Browse files
committed
simplified the implementation of Dijkstra's Algorithm
1 parent 6d13861 commit 4f94036

File tree

1 file changed

+14
-30
lines changed

1 file changed

+14
-30
lines changed

Sources/Search.swift

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -247,36 +247,20 @@ public extension WeightedGraph {
247247
/// - parameter startDistance: The distance to get to the root node (typically 0).
248248
/// - returns: Returns a tuple of two things: the first, an array containing the distances, the second, a dictionary containing the edge to reach each vertex. Use the function pathDictToPath() to convert the dictionary into something useful for a specific point.
249249
public func dijkstra( root: Int, startDistance: W) -> ([W?], [Int: WeightedEdge<W>]) {
250-
var distances: [W?] = [W?](repeating: nil, count: vertexCount)
251-
distances[root] = startDistance
252-
var queue: PriorityQueue<DijkstraNode<W>> = PriorityQueue<DijkstraNode<W>>(ascending: true)
253-
var pathDict: [Int: WeightedEdge<W>] = [Int: WeightedEdge<W>]()
254-
queue.push(DijkstraNode(vertice: root, distance: startDistance))
250+
var distances: [W?] = [W?](repeating: nil, count: vertexCount) // how far each vertex is from start
251+
distances[root] = startDistance // the start vertex is startDistance away
252+
var pq: PriorityQueue<DijkstraNode<W>> = PriorityQueue<DijkstraNode<W>>(ascending: true)
253+
var pathDict: [Int: WeightedEdge<W>] = [Int: WeightedEdge<W>]() // how we got to each vertex
254+
pq.push(DijkstraNode(vertex: root, distance: startDistance))
255255

256-
while !queue.isEmpty {
257-
let u = queue.pop()!.vertice
258-
for e in edgesForIndex(u) {
259-
if let we = e as? WeightedEdge<W> {
260-
//if queue.contains(we.v) {
261-
var alt: W
262-
if let dist = distances[we.u] {
263-
alt = we.weight + dist
264-
} else {
265-
alt = we.weight
266-
}
267-
if let dist = distances[we.v] {
268-
if alt < dist {
269-
distances[we.v] = alt
270-
pathDict[we.v] = we
271-
}
272-
} else {
273-
if !(we.v == root) {
274-
distances[we.v] = alt
275-
pathDict[we.v] = we
276-
queue.push(DijkstraNode(vertice: we.v, distance: alt))
277-
}
278-
}
279-
//}
256+
while let u = pq.pop()?.vertex { // explore the next closest vertex
257+
guard let distU = distances[u] else { continue } // should already have seen it
258+
for we in edgesForIndex(u) as! [WeightedEdge<W>] { // look at every edge/vertex from the vertex in question
259+
let distV = distances[we.v] // the old distance to this vertex
260+
if distV == nil || distV! > we.weight + distU { // if we have no old distance or we found a shorter path
261+
distances[we.v] = we.weight + distU // update the distance to this vertex
262+
pathDict[we.v] = we // update the edge on the shortest path to this vertex
263+
pq.push(DijkstraNode(vertex: we.v, distance: we.weight + distU)) // explore it soon
280264
}
281265
}
282266
}
@@ -300,7 +284,7 @@ public extension WeightedGraph {
300284
/// Represents a node in the priority queue used
301285
/// for selecting the next
302286
struct DijkstraNode<D: Comparable>: Comparable, Equatable {
303-
let vertice: Int
287+
let vertex: Int
304288
let distance: D
305289

306290
static func < <D: Comparable>(lhs: DijkstraNode<D>, rhs: DijkstraNode<D>) -> Bool {

0 commit comments

Comments
 (0)