\newpage \subsection{All-Pair Shortest Paths} We can also use $n$-times dijkstra or any other shortest path algorithm, or any of the dedicated ones \subsubsection{Floyd-Warshall Algorithm} \begin{definition}[]{Floyd-Warshall Algorithm} The \textbf{Floyd-Warshall Algorithm} is a dynamic programming algorithm used to compute the shortest paths between all pairs of vertices in a weighted graph. \end{definition} \begin{algo}{FloydWarshall(G)} \Procedure{Floyd-Warshall}{$G = (V, E)$} \State Initialize distance matrix $d[i][j]$: $d[i][j] = \begin{cases} 0 & \text{if } i = j \\ w(i, j) & \text{if } (i, j) \in E \\ \infty & \text{otherwise} \end{cases}$ \For{each intermediate vertex $k \in V$} \For{each pair of vertices $i, j \in V$} \State $d[i][j] \gets \min(d[i][j], d[i][k] + d[k][j])$ \EndFor \EndFor \State \textbf{Return} $d$ \EndProcedure \end{algo} \begin{properties}[]{Characteristics of Floyd-Warshall Algorithm} \begin{itemize} \item \textbf{Time Complexity:} \tco{|V|^3}. \item Works for graphs with negative edge weights but no negative weight cycles. \item Computes shortest paths for all pairs in one execution. \end{itemize} \end{properties} \begin{usage}[]{Floyd-Warshall Algorithm} The Floyd-Warshall algorithm computes shortest paths between all pairs of vertices in a weighted graph (handles negative weights but no negative cycles). \begin{enumerate} \item \textbf{Initialize:} \begin{itemize} \item Create a distance matrix \(D\), where \(D[i][j]\) is the weight of the edge from vertex \(i\) to vertex \(j\), or infinity if no edge exists. Set \(D[i][i] = 0\). \end{itemize} \item \textbf{Iterate Over Intermediate Vertices:} \begin{itemize} \item For each vertex \(k\) (acting as an intermediate vertex): \begin{itemize} \item Update \(D[i][j]\) for all pairs of vertices \(i, j\) using: \[ D[i][j] = \min(D[i][j], D[i][k] + D[k][j]) \] \end{itemize} \end{itemize} \item \textbf{Repeat:} \begin{itemize} \item Repeat for all vertices as intermediate vertices (\(k = 1, 2, \ldots, n\)). \end{itemize} \item \textbf{End:} \begin{itemize} \item The final distance matrix \(D\) contains the shortest path distances between all pairs of vertices. \end{itemize} \end{enumerate} \end{usage} \newpage \subsubsection{Johnson's Algorithm} \begin{definition}[]{Johnson's Algorithm} The \textbf{Johnson’s Algorithm} computes shortest paths between all pairs of vertices in a sparse graph. It uses the Bellman-Ford algorithm as a preprocessing step to reweight edges and ensures all weights are non-negative. \end{definition} \begin{properties}[]{Characteristics of Johnson's Algorithm} \begin{itemize} \item \textbf{Steps:} \begin{enumerate} \item Add a new vertex $s$ with edges of weight $0$ to all vertices. \item Run Bellman-Ford from $s$ to detect negative cycles and compute vertex potentials. \item Reweight edges to remove negative weights. \item Use Dijkstra's algorithm for each vertex to find shortest paths. \end{enumerate} \item \textbf{Time Complexity:} \tco{|V| \cdot (|E| + |V| \log |V|)}. \item Efficient for sparse graphs compared to Floyd-Warshall. \end{itemize} \end{properties} \begin{usage}[]{Johnson's Algorithm} Johnson's algorithm computes shortest paths between all pairs of vertices in a weighted graph (handles negative weights but no negative cycles). \begin{enumerate} \item \textbf{Add a New Vertex:} \begin{itemize} \item Add a new vertex \(s\) to the graph and connect it to all vertices with zero-weight edges. \end{itemize} \item \textbf{Run Bellman-Ford:} \begin{itemize} \item Use the Bellman-Ford algorithm starting from \(s\) to compute the shortest distance \(h[v]\) from \(s\) to each vertex \(v\). \item If a negative-weight cycle is detected, stop. \end{itemize} \item \textbf{Reweight Edges:} \begin{itemize} \item For each edge \(u \to v\) with weight \(w(u, v)\), reweight it as: \[ w'(u, v) = w(u, v) + h[u] - h[v] \] \item This ensures all edge weights are non-negative. \end{itemize} \item \textbf{Run Dijkstra's Algorithm:} \begin{itemize} \item For each vertex \(v\), use Dijkstra's algorithm to compute the shortest paths to all other vertices. \end{itemize} \item \textbf{Adjust Back:} \begin{itemize} \item Convert the distances back to the original weights using: \[ d'(u, v) = d'(u, v) - h[u] + h[v] \] \end{itemize} \item \textbf{End:} \begin{itemize} \item The resulting shortest path distances between all pairs of vertices are valid. \end{itemize} \end{enumerate} \end{usage} \subsubsection{Comparison} \begin{table}[h!] \centering \begin{tabular}{lccc} \toprule \textbf{Algorithm} & \textbf{Primary Use} & \textbf{Time Complexity} & \textbf{Remarks} \\ \midrule Floyd-Warshall & AP-SP & \tco{|V|^3} & Handles negative weights \\ Johnson’s Algorithm & AP-SP (sparse graphs) & \tco{|V|(|E| + |V| \log |V|)} & Requires reweighting \\ \bottomrule \end{tabular} \caption{Comparison of the All-Pair Shortest path (AP-SP) algorithms discussed in the lecture} \end{table}