Principle
We know that using the Breadth-first search algorithm can find the shortest path to a target, but this algorithm is not considered weight , so after we have added weights for each edge, we need to use the Dijkstra algorithm to find the weights and the smallest path.
In fact, the principle is very simple, our ultimate goal is to calculate the sum of the weights of each node to the starting point, at the same time get this weight and the path array.
Then the weight and the smallest of the nature is the result we want.
There are several core ideas in this algorithm:
- When we traverse to a node, we calculate the weight of the node to the starting point and after =, the node is not used, or deleted or marked as inspected
- When a neighbor node of that node is prefixed with a value less than the neighbor node, the data from the new neighbor node
There are many ways to implement this algorithm, in which we encapsulate some data directly into a node.
Vertex
Vertex.swiftimport Foundationopen class Vertex { open var identifier: String open var neighbors: [(Vertex, Double)] = [] open var pathLengthFromStart = Double.infinity open var pathVerticesFromStart: [Vertex] = [] public init(identifier: String) { self.identifier = identifier } open func clearCache() { pathLengthFromStart = Double.infinity pathVerticesFromStart = [] }}extension Vertex: Hashable { open var hashValue: Int { return identifier.hashValue }}extension Vertex: Equatable { public static func ==(lhs: Vertex, rhs: Vertex) -> Bool { return lhs.hashValue == rhs.hashValue }}
Dijkstra
Dijkstra.swiftimport Foundationpublic class Dijkstra {private var totalvertices:set<vertex> public init (vert ices:set<vertex>) {totalvertices = vertices} private func ClearCache () {TOTALVERTICES.FOREAC h {$0.clearcache ()}} public func findshortestpaths (from Startvertex:vertex) {ClearCache () var cur Rentvertices = self.totalvertices Startvertex.pathlengthfromstart = 0 StartVertex.pathVerticesFromStart.appe nd (Startvertex) var Currentvertex:vertex? = Startvertex while let vertex = Currentvertex {currentvertices.remove (vertex) Let Filteredn Eighbors = vertex.neighbors.filter {currentvertices.contains ($0.0)} for neighbor in Filteredneighbors { Let Neighborvertex = neighbor.0 let weight = neighbor.1 let Theoreticnewweight = V Ertex.pathlengthfromstart + Weight If theoreticnewweight < Neighborvertex.pathLengthfromstart {Neighborvertex.pathlengthfromstart = Theoreticnewweight neighborve Rtex.pathverticesfromstart = Vertex.pathverticesfromstart neighborVertex.pathVerticesFromStart.append (n Eighborvertex)}} if currentvertices.isempty {Currentvertex = nil Break} Currentvertex = currentvertices.min {$0.pathlengthfromstart < $1.pathlength Fromstart}}}}
Demonstrate
We'll show you this example.
: Playground-noun:a place where people can playimport foundation//last checked with Xcode 9.0b4#if Swift (>=4.0) pr Int ("Hello, Swift 4!") #endifvar vertices:set<vertex> = Set ()//Create Vertexsvar Vertexa = Vertex (identifier: "A") var Vertexb = Vertex (i Dentifier: "B") var vertexc = Vertex (identifier: "C") var vertexd = Vertex (identifier: "D") var Vertexe = Vertex (identifier: "E") var vertexf = Vertex (identifier: "F")///Setting NeighborsvertexA.neighbors.append (contentsof: [(Vertexb, 5), ( Vertexd, 2)] VertexB.neighbors.append (contentsof: [(Vertexc, 4), (Vertexe, 2)]) VertexC.neighbors.append (contentsof: [(Vertexe, 6), (VERTEXF, 3)]) VertexD.neighbors.append (contentsof: [(VERTEXB, 8), (Vertexe, 7)]) VertexE.neighbors.append (contentsof: [(VERTEXF, 1) ]) Vertices.insert (vertexa) Vertices.insert (VERTEXB) Vertices.insert (VERTEXC) Vertices.insert (VertexD) Vertices.insert (Vertexe) Vertices.insert (VERTEXF) Let Dijkstra = Dijkstra (vertices:vertices) Dijkstra.findshortestpaths (From:vertexa) for VERtex in vertices {let paths = Vertex.pathVerticesFromStart.map ({$0.identifier}) print ("(a=>" + Vertex.identifi ER + "):" + paths.joined (separator: ")}
Printing results:
(A=>B): A -> B(A=>A): A(A=>F): A -> B -> E -> F(A=>C): A -> B -> C(A=>D): A -> D(A=>E): A -> B -> E
The main code comes from Dijkstra
Dijkstra algorithm (Swift version)