You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A graph that can have multiple edges between the same pair of nodes. In a road network this could, for example, be used to represent different routes with the same start and end point.
@@ -850,9 +859,14 @@ Finds the shortest **greedy** path via a **[priority queue](computer-science.md#
For your exam, you don't need to remember how a heap works or the intracacies of the time complexities below. Just remember that there's 2 time complexities and they differ based on implimentation. Maybe learn how to justify one of them in case you need to write a proof.
866
+
853
867
Worst case performance if using a [priority queue](computer-science.md#priority-queue) (Fibonacci heap version):
854
868
$$
855
-
\displaystyle O(|E|+|V|\log |V|) \newline
869
+
\boxed{\displaystyle O(|E|+|V|\log |V|)} \newline
856
870
\text{or equivalently,} \newline
857
871
\displaystyle O(|V|\log(|V|+|E|))
858
872
$$
@@ -861,8 +875,40 @@ This is because you're initialising each node into `unexplored`. Which is both $
861
875
862
876
Then considering the inner loop of `for each neighbour N of V do`, you can't immediately think of it as having that automatic coeficcient of $|V|$ because it's in that while loop. Instead, think of it on a higher level and what it's doing overall. That loop is the mechanism for relaxing edges if you find a shorter path. And when you run the algorithm you will see that relaxation is done **once per edge**[^dijkstra-edge]. So that contributes the extra term of $O(|E|)$ for a final time complexity of $O(|V|\log(|V|+|E|)) \equiv O(|E|+|V|\log |V|)$
863
877
864
-
Worst case performance when using an array:
865
-
$$\displaystyle O(|V^2|)$$
878
+
<br>
879
+
880
+
**Worst case performance when using an array:**
881
+
882
+
$$
883
+
\boxed{
884
+
\displaystyle O(|V|^2)
885
+
}
886
+
$$
887
+
888
+
When using an array, Dijkstra's algorithm must loop over **all nodes** to pick the next closest node. This is clearly a lot slower than using a [priority queue](computer-science.md#priority-queue), where that operation can be done much faster (e.g. $ O(\log |V|) $).
889
+
890
+
The initial naive time complexity is:
891
+
892
+
$$
893
+
O(|V|^2 + |E|)
894
+
$$
895
+
896
+
- The $ O(|V|^2) $ comes from scanning all $ |V| $ nodes every time we select the next node — this happens $ |V| $ times.
897
+
- The $ O(|E|) $ comes from relaxing edges, which happens once per edge over the whole run.
898
+
899
+
In asymptotic analysis, we drop lower-order terms. Since even in the worst case $ |E| \le |V|^2 $, we simplify:
900
+
901
+
$$
902
+
O(|V|^2 + |E|) = O(|V|^2)
903
+
$$
904
+
905
+
As a matter of fact, for [simple](#simple-graph)[connected](#connected-graph) graphs the boundary of $|E|$ proves[^edge-boundaries] that inequality.
906
+
907
+
You don't need to remember all the maths — just remember that when using an **array**, Dijkstra runs in **$ O(|V|^2) $** time.
908
+
909
+
[^edge-boundaries]: The minimum bound are [trees](#trees) and the maximum bound are [complete graphs](#complete-graphs) which are noted in the [simple graph section](#simple-graph)
910
+
911
+
---
866
912
867
913
- Finds shortest path from starting node, to any other location, not just the desired location.
868
914
- Works on weighted, weighted graphs and weighted digraphs. **Where no negative weight cycles exist**
@@ -871,7 +917,7 @@ $$\displaystyle O(|V^2|)$$
871
917
872
918
Pseudocode
873
919
874
-
```js
920
+
```js title="Dijkstras with a priority queue"
875
921
Algorithm Dijkstra(Graph, source):
876
922
// initialise the algorithm
877
923
for each vertex Vin Graph G=(V,E) do
@@ -880,7 +926,7 @@ for each vertex V in Graph G=(V,E) do
880
926
add V to unexplored // Unexplored nodes
881
927
End do
882
928
883
-
dist[source] :=0// Distance from source to source
929
+
dist[source] :=0// Distance from source to source
884
930
885
931
while unexplored is not empty do
886
932
V:= vertex in unexplored with minimum dist[V] // Greedy Priority Queue (1)
@@ -896,7 +942,7 @@ while unexplored is not empty do
896
942
End do// shortest path information in dist[], pred[]
897
943
```
898
944
899
-
1. With Fibonacci heap, this discrete operation is `O(log |V|)`
945
+
1. With Fibonacci heap, this discrete operation is `O(log |V|)`. But once again, not something you **need** to remember
0 commit comments