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
Copy file name to clipboardExpand all lines: docs/graphs.md
+18-5Lines changed: 18 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -845,12 +845,21 @@ Scenarios:
845
845
846
846
Pronounced *Dikestra*.
847
847
Finds the shortest **greedy** path via a **[priority queue](computer-science.md#priority-queue)**.
848
-
- Not [Dynamic Programming](algorithms.md#dynamic-programming)
848
+
849
+
- Although dijkstras does store information as it is building a solution, it is not [Dynamic Programming](algorithms.md#dynamic-programming) because it does not explicitly or fully solve any discrete sub-problems of the original input. This is debated, but for the sake of VCE just remember it as [greedy](algorithms.md#greedy)
Worst case performance if using a [priority queue](computer-science.md#priority-queue):
853
-
$$\displaystyle O(|E|+|V|\log |V|)$$
853
+
Worst case performance if using a [priority queue](computer-science.md#priority-queue) (Fibonacci heap version):
854
+
$$
855
+
\displaystyle O(|E|+|V|\log |V|) \newline
856
+
\text{or equivalently,} \newline
857
+
\displaystyle O(|V|\log(|V|+|E|))
858
+
$$
859
+
860
+
This is because you're initialising each node into `unexplored`. Which is both $O(|V|)$ and setting the size of `unexplored` to $|V|$ which means the `while` loop will run at most $O(|V|)$ times. And the pop operation for a vertex with with minimum distance from the priority queue (Fibonacci heap) is $O(\log |V|)$. Which means you are running $O(|V| \log |V|)$ operations there.
861
+
862
+
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|)$
854
863
855
864
Worst case performance when using an array:
856
865
$$\displaystyle O(|V^2|)$$
@@ -874,11 +883,11 @@ End do
874
883
dist[source] :=0// Distance from source to source
875
884
876
885
while unexplored is not empty do
877
-
V:= vertex in unexplored with minimum dist[V] // Greedy Priority Queue
886
+
V:= vertex in unexplored with minimum dist[V] // Greedy Priority Queue (1)
878
887
remove V from unexplored
879
888
for each neighbour NofVdo
880
889
thisDist := dist[V] +weight(V, N)
881
-
if (thisDist < dist[N]) then
890
+
if (thisDist < dist[N]) then
882
891
// A shorter path to N has been found
883
892
dist[N] := thisDist // Update shortest path
884
893
pred[N] :=V// Update path predecessor
@@ -887,10 +896,14 @@ while unexplored is not empty do
887
896
End do// shortest path information in dist[], pred[]
888
897
```
889
898
899
+
1. With Fibonacci heap, this discrete operation is `O(log |V|)`
900
+
890
901
**Limitations**
891
902
892
903
- Can't use negative weights
893
904
905
+
[^dijkstra-edge]: On an undirected graph, you can argue that it does some edges twice which would make it $2|E|$. But in that case you use the convention that an undirected graph has one edge in each direction, so $2|E|$ is now $|E|$. Either way, it's still asymptotically $|E|$
0 commit comments