Skip to content

Commit 07563e0

Browse files
committed
add astar reference in readme
1 parent 33e5572 commit 07563e0

File tree

1 file changed

+30
-28
lines changed

1 file changed

+30
-28
lines changed

Diff for: Dijkstra Algorithm/README.md

+30-28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Weighted graph general concepts
22

3-
Every weighted graph should contain:
3+
Every weighted graph should contain:
44
1. Vertices/Nodes (I will use "vertex" in this readme).
55

66
<img src="Images/Vertices.png" height="250" />
@@ -11,11 +11,11 @@ Every weighted graph should contain:
1111

1212
<img src="Images/DirectedGraph.png" height="250" />
1313

14-
3. Weights for every edge.
14+
3. Weights for every edge.
1515

1616
<img src="Images/WeightedDirectedGraph.png" height="250" />
1717

18-
Final result.
18+
Final result.
1919
Directed weighted graph:
2020

2121
<img src="Images/WeightedDirectedGraphFinal.png" height="250" />
@@ -44,7 +44,9 @@ When all vertices are marked as visited, the algorithm's job is done. Now, you c
4444

4545
I have created **VisualizedDijkstra.playground** game/tutorial to improve your understanding of the algorithm's flow. Besides, below is step by step algorithm's description.
4646

47-
## Example
47+
A short sidenote. The Swift Algorithm Club also contains the A* algorithm, which essentially is a faster version of Dijkstra's algorithm for which the only extra prerequisite is you have to know where the destination is located.
48+
49+
## Example
4850
Let's imagine that you want to go to the shop. Your house is A vertex and there are 4 possible stores around your house. How to find the closest one/ones? Luckily, you have a graph that connects your house with all these stores. So, you know what to do :)
4951

5052
### Initialisation
@@ -95,7 +97,7 @@ After this step graph has this state:
9597

9698
### Step 1
9799

98-
Then we check all of its neighbours.
100+
Then we check all of its neighbours.
99101
If checking vertex path length from start + edge weight is smaller than neighbour's path length from start then we set neighbour's path length from start new value and append to its pathVerticesFromStart array new vertex: checkingVertex. Repeat this action for every vertex.
100102

101103
for clarity:
@@ -120,7 +122,7 @@ And its state is here:
120122

121123
### Step 2
122124

123-
From now we repeat all actions again and fill our table with new info!
125+
From now we repeat all actions again and fill our table with new info!
124126

125127
<img src="Images/image4.png" height="250" />
126128

@@ -161,20 +163,20 @@ From now we repeat all actions again and fill our table with new info!
161163
| Path Vertices From Start | [A] | [A, B] | [A, B, C]| [A, D] | [A, D, E ] |
162164

163165

164-
## Code implementation
166+
## Code implementation
165167
First of all, let’s create class that will describe any Vertex in the graph.
166168
It is pretty simple
167169
```swift
168170
open class Vertex {
169171

170172
//Every vertex should be unique that's why we set up identifier
171173
open var identifier: String
172-
173-
//For Dijkstra every vertex in the graph should be connected with at least one other vertex. But there can be some usecases
174+
175+
//For Dijkstra every vertex in the graph should be connected with at least one other vertex. But there can be some usecases
174176
//when you firstly initialize all vertices without neighbours. And then on next iteration you set up their neighbours. So, initially neighbours is an empty array.
175177
//Array contains tuples (Vertex, Double). Vertex is a neighbour and Double is as edge weight to that neighbour.
176178
open var neighbours: [(Vertex, Double)] = []
177-
179+
178180
//As it was mentioned in the algorithm description, default path length from start for all vertices should be as much as possible.
179181
//It is var because we will update it during the algorithm execution.
180182
open var pathLengthFromStart = Double.infinity
@@ -215,77 +217,77 @@ We've created a base for our algorithm. Now let's create a house :)
215217
Dijkstra's realisation is really straightforward.
216218
```swift
217219
public class Dijkstra {
218-
//This is a storage for vertices in the graph.
220+
//This is a storage for vertices in the graph.
219221
//Assuming that our vertices are unique we can use Set instead of array. This approach will bring some benefits later.
220222
private var totalVertices: Set<Vertex>
221223

222224
public init(vertices: Set<Vertex>) {
223225
totalVertices = vertices
224226
}
225227

226-
//Remember clearCache function in the Vertex class implementation?
228+
//Remember clearCache function in the Vertex class implementation?
227229
//This is just a wrapper that cleans cache for all stored vertices.
228230
private func clearCache() {
229231
totalVertices.forEach { $0.clearCache() }
230232
}
231233

232234
public func findShortestPaths(from startVertex: Vertex) {
233-
//Before we start searching the shortest path from startVertex,
235+
//Before we start searching the shortest path from startVertex,
234236
//we need to clear vertices cache just to be sure that out graph is clean.
235-
//Remember that every Vertex is a class and classes are passed by reference.
237+
//Remember that every Vertex is a class and classes are passed by reference.
236238
//So whenever you change vertex outside of this class it will affect this vertex inside totalVertices Set
237239
clearCache()
238240
//Now all our vertices have Double.infinity pathLengthFromStart and an empty pathVerticesFromStart array.
239-
241+
240242
//The next step in the algorithm is to set startVertex pathLengthFromStart and pathVerticesFromStart
241243
startVertex.pathLengthFromStart = 0
242244
startVertex.pathVerticesFromStart.append(startVertex)
243-
245+
244246
//Here starts the main part. We will use while loop to iterate through all vertices in the graph.
245247
//For this purpose we define currentVertex variable which we will change in the end of each while cycle.
246248
var currentVertex: Vertex? = startVertex
247-
249+
248250
while let vertex = currentVertex {
249-
251+
250252
//Next line of code is an implementation of setting vertex as visited.
251253
//As it has been said, we should check only unvisited vertices in the graph,
252254
//So why don't just delete it from the set? This approach let us skip checking for *"if !vertex.visited then"*
253255
totalVertices.remove(vertex)
254-
256+
255257
//filteredNeighbours is an array that contains current vertex neighbours which aren't yet visited
256258
let filteredNeighbours = vertex.neighbours.filter { totalVertices.contains($0.0) }
257-
259+
258260
//Let's iterate through them
259261
for neighbour in filteredNeighbours {
260262
//These variable are more representative, than neighbour.0 or neighbour.1
261263
let neighbourVertex = neighbour.0
262264
let weight = neighbour.1
263-
264-
//Here we calculate new weight, that we can offer to neighbour.
265+
266+
//Here we calculate new weight, that we can offer to neighbour.
265267
let theoreticNewWeight = vertex.pathLengthFromStart + weight
266-
268+
267269
//If it is smaller than neighbour's current pathLengthFromStart
268270
//Then we perform this code
269271
if theoreticNewWeight < neighbourVertex.pathLengthFromStart {
270-
272+
271273
//set new pathLengthFromStart
272274
neighbourVertex.pathLengthFromStart = theoreticNewWeight
273-
275+
274276
//set new pathVerticesFromStart
275277
neighbourVertex.pathVerticesFromStart = vertex.pathVerticesFromStart
276-
278+
277279
//append current vertex to neighbour's pathVerticesFromStart
278280
neighbourVertex.pathVerticesFromStart.append(neighbourVertex)
279281
}
280282
}
281-
283+
282284
//If totalVertices is empty, i.e. all vertices are visited
283285
//Than break the loop
284286
if totalVertices.isEmpty {
285287
currentVertex = nil
286288
break
287289
}
288-
290+
289291
//If loop is not broken, than pick next vertex for checkin from not visited.
290292
//Next vertex pathLengthFromStart should be the smallest one.
291293
currentVertex = totalVertices.min { $0.pathLengthFromStart < $1.pathLengthFromStart }

0 commit comments

Comments
 (0)