mirror of
https://github.com/janishutz/eth-summaries.git
synced 2025-11-25 10:34:23 +00:00
Move A&D summary
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
\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}
|
||||
113
semester1/algorithms-and-datastructures/parts/graphs/bfs-dfs.tex
Normal file
113
semester1/algorithms-and-datastructures/parts/graphs/bfs-dfs.tex
Normal file
@@ -0,0 +1,113 @@
|
||||
\newpage
|
||||
\subsection{Topological Sorting / Ordering}
|
||||
\begin{definition}[]{Topological Ordering}
|
||||
A \textbf{topological ordering} of a directed acyclic graph (DAG) $G = (V, E)$ is a linear ordering of its vertices such that for every directed edge $(u, v) \in E$, vertex $u$ comes before vertex $v$ in the ordering.
|
||||
\end{definition}
|
||||
|
||||
\begin{properties}[]{Topological Ordering}
|
||||
\begin{itemize}
|
||||
\item A graph has a topological ordering if and only if it is a DAG.
|
||||
\item The ordering is not unique if the graph contains multiple valid sequences of vertices.
|
||||
\item Common algorithms to compute topological ordering:
|
||||
\begin{itemize}
|
||||
\item \textbf{DFS-based Approach:} Perform a depth-first search and record vertices in reverse postorder.
|
||||
\item \textbf{Kahn’s Algorithm:} Iteratively remove vertices with no incoming edges while maintaining order.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
|
||||
|
||||
|
||||
\newpage
|
||||
\subsection{Graph search}
|
||||
\subsubsection{DFS}
|
||||
\begin{definition}[]{Depth-First Search (DFS)}
|
||||
\textbf{Depth-First Search} is an algorithm for traversing or searching a graph by exploring as far as possible along each branch before backtracking.
|
||||
\end{definition}
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Depth-First Search (Recursive)}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure{DFS}{$v$}
|
||||
\State \textbf{Mark} $v$ as visited
|
||||
\For{each neighbor $u$ of $v$}
|
||||
\If{$u$ is not visited}
|
||||
\State \Call{DFS}{$u$}
|
||||
\EndIf
|
||||
\EndFor
|
||||
\EndProcedure
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
\begin{properties}[]{Depth-First Search}
|
||||
\begin{itemize}
|
||||
\item Can be implemented recursively or iteratively (using a stack).
|
||||
\item Time complexity: \tco{|V| + |E|}, where $|V|$ is the number of vertices and $|E|$ is the number of edges.
|
||||
\item Used for:
|
||||
\begin{itemize}
|
||||
\item Detecting cycles in directed and undirected graphs.
|
||||
\item Finding connected components in undirected graphs.
|
||||
\item Computing topological ordering in a DAG.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
|
||||
\subsubsection{BFS}
|
||||
\begin{definition}[]{Breadth-First Search (BFS)}
|
||||
\textbf{Breadth-First Search} is an algorithm for traversing or searching a graph by exploring all neighbors of a vertex before moving to the next level of neighbors.
|
||||
\end{definition}
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Breadth-First Search (Iterative)}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure{BFS}{$start$}
|
||||
\State \textbf{Initialize} queue $Q$ and mark $start$ as visited
|
||||
\State \textbf{Enqueue} $start$ into $Q$
|
||||
\While{$Q$ is not empty}
|
||||
\State $v \gets \textbf{Dequeue}(Q)$
|
||||
\For{each neighbor $u$ of $v$}
|
||||
\If{$u$ is not visited}
|
||||
\State \textbf{Mark} $u$ as visited
|
||||
\State \textbf{Enqueue} $u$ into $Q$
|
||||
\EndIf
|
||||
\EndFor
|
||||
\EndWhile
|
||||
\EndProcedure
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
\begin{properties}[]{Breadth-First Search}
|
||||
\begin{itemize}
|
||||
\item Implements a queue-based approach for level-order traversal.
|
||||
\item Time complexity: \tco{|V| + |E|}.
|
||||
\item Used for:
|
||||
\begin{itemize}
|
||||
\item Finding shortest paths in unweighted graphs.
|
||||
\item Checking bipartiteness.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
\begin{example}[]{DFS and BFS Traversal}
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[node distance=1.5cm, main/.style={circle, draw, fill=blue!20, minimum size=10mm, inner sep=0pt}]
|
||||
% Graph vertices
|
||||
\node[main] (1) {1};
|
||||
\node[main] (2) [above right of=1] {2};
|
||||
\node[main] (3) [below right of=1] {3};
|
||||
\node[main] (4) [right of=2] {4};
|
||||
\node[main] (5) [right of=3] {5};
|
||||
|
||||
% Edges
|
||||
\draw (1) -- (2);
|
||||
\draw (1) -- (3);
|
||||
\draw (2) -- (4);
|
||||
\draw (3) -- (5);
|
||||
\draw (4) -- (5);
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
\textbf{DFS Traversal:} Starting at $1$, a possible traversal is $1 \to 2 \to 4 \to 5 \to 3$.\\
|
||||
\textbf{BFS Traversal:} Starting at $1$, a possible traversal is $1 \to 2 \to 3 \to 4 \to 5$.
|
||||
\end{example}
|
||||
@@ -0,0 +1,54 @@
|
||||
\newpage
|
||||
\subsection{Connected Components}
|
||||
\begin{definition}[]{Connected Component}
|
||||
A \textbf{connected component} of a graph $G = (V, E)$ is a maximal subset of vertices $C \subseteq V$ such that:
|
||||
\begin{itemize}
|
||||
\item For every pair of vertices $u, v \in C$, there exists a path connecting $u$ and $v$.
|
||||
\item Adding any vertex $w \notin C$ to $C$ would violate the connectedness condition.
|
||||
\end{itemize}
|
||||
\end{definition}
|
||||
|
||||
\begin{remarks}[]{Key Points About Connected Components}
|
||||
\begin{itemize}
|
||||
\item \textbf{Undirected Graphs:} A connected component is a subgraph where any two vertices are connected by a path, and which is connected to no additional vertices in the graph.
|
||||
\item \textbf{Directed Graphs:} There are two types of connected components:
|
||||
\begin{itemize}
|
||||
\item \textbf{Strongly Connected Component:} A maximal subset of vertices where every vertex is reachable from every other vertex (considering edge direction).
|
||||
\item \textbf{Weakly Connected Component:} A maximal subset of vertices where connectivity is considered by ignoring edge directions.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{remarks}
|
||||
|
||||
\begin{example}[]{Connected Components in a Graph}
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[node distance=1.5cm, main/.style={circle, draw, fill=blue!20, minimum size=10mm, inner sep=0pt}]
|
||||
% Connected component 1
|
||||
\node[main] (1) {1};
|
||||
\node[main] (2) [right of=1] {2};
|
||||
\node[main] (3) [below of=1] {3};
|
||||
\draw (1) -- (2);
|
||||
\draw (1) -- (3);
|
||||
\draw (2) -- (3);
|
||||
|
||||
% Connected component 2
|
||||
\node[main] (4) [right of=2, xshift=2cm] {4};
|
||||
\node[main] (5) [right of=4] {5};
|
||||
\draw (4) -- (5);
|
||||
|
||||
% Isolated vertex (another component)
|
||||
\node[main] (6) [below of=5, yshift=-1cm] {6};
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
\end{example}
|
||||
|
||||
\begin{remarks}[]{Understanding the Example}
|
||||
\begin{itemize}
|
||||
\item In the given undirected graph:
|
||||
\begin{itemize}
|
||||
\item \textbf{Component 1:} $\{1, 2, 3\}$ (fully connected subgraph).
|
||||
\item \textbf{Component 2:} $\{4, 5\}$ (connected by a single edge).
|
||||
\item \textbf{Component 3:} $\{6\}$ (an isolated vertex).
|
||||
\end{itemize}
|
||||
\item These subsets are disjoint and collectively partition the graph's vertex set $V$.
|
||||
\end{itemize}
|
||||
\end{remarks}
|
||||
@@ -0,0 +1,73 @@
|
||||
\newsection
|
||||
\section{Graph theory}
|
||||
\begin{definition}[]{Graphs: Directed and Undirected}
|
||||
A \textbf{graph} $G = (V, E)$ consists of:
|
||||
\begin{itemize}
|
||||
\item A set of \textbf{vertices} (or nodes) $V$, and
|
||||
\item A set of \textbf{edges} $E$, representing connections between pairs of vertices.
|
||||
\end{itemize}
|
||||
Graphs can be classified into:
|
||||
\begin{itemize}
|
||||
\item \textbf{Undirected Graphs:} Edges have no direction, represented as unordered pairs $\{u, v\}$.
|
||||
\item \textbf{Directed Graphs (Digraphs):} Edges have a direction, represented as ordered pairs $(u, v)$.
|
||||
\end{itemize}
|
||||
\end{definition}
|
||||
|
||||
\begin{terms}[]{Graph Theory}
|
||||
\begin{itemize}
|
||||
\item \textbf{Adjacent (Neighbors):} Two vertices $u$ and $v$ are adjacent if there is an edge between them.
|
||||
\item \textbf{Degree:}
|
||||
\begin{itemize}
|
||||
\item \textbf{Undirected Graph:} The degree of a vertex $v$ is the number of edges incident to it.
|
||||
\item \textbf{Directed Graph:}
|
||||
\begin{itemize}
|
||||
\item \textbf{In-Degree:} Number of incoming edges to $v$.
|
||||
\item \textbf{Out-Degree:} Number of outgoing edges from $v$.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\item \textbf{Path:} A sequence of vertices where each adjacent pair is connected by an edge.
|
||||
\begin{itemize}
|
||||
\item \textbf{Simple Path:} A path with no repeated vertices.
|
||||
\item \textbf{Cycle:} A path that starts and ends at the same vertex.
|
||||
\end{itemize}
|
||||
\item \textbf{Connected Graph:} A graph where there is a path between any two vertices.
|
||||
\begin{itemize}
|
||||
\item \textbf{Strongly Connected:} In a directed graph, every vertex is reachable from every other vertex.
|
||||
\item \textbf{Weakly Connected:} A directed graph becomes connected if the direction of edges is ignored.
|
||||
\end{itemize}
|
||||
\item \textbf{Subgraph:} A graph formed from a subset of vertices and edges of the original graph.
|
||||
\item \textbf{Complete Graph:} A graph in which every pair of vertices is connected by an edge.
|
||||
\item \textbf{Weighted Graph:} A graph where each edge has an associated weight or cost.
|
||||
\item \textbf{Multigraph:} A graph that may have multiple edges (parallel edges) between the same pair of vertices.
|
||||
\item \textbf{Self-Loop:} An edge that connects a vertex to itself.
|
||||
\item \textbf{Bipartite Graph:} A graph whose vertices can be divided into two disjoint sets such that every edge connects a vertex in one set to a vertex in the other set.
|
||||
\item \textbf{Tree:} A graph is a tree if it is connected and has no cycles (sufficient condition), a tree has $n - 1$ edges for $n$ vertices (necessary condition).
|
||||
\item \textbf{Reachability:} A vertex $u$ is called \textit{reachable} from $v$, if there exists a walk or path with endpoints $u$ and $v$.
|
||||
\end{itemize}
|
||||
\end{terms}
|
||||
|
||||
\begin{example}[]{Directed and Undirected Graphs}
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[node distance=1.5cm, main/.style={circle, draw, fill=blue!20, minimum size=10mm, inner sep=0pt}]
|
||||
% Undirected graph
|
||||
\node[main] (1) {1};
|
||||
\node[main] (2) [right of=1] {2};
|
||||
\node[main] (3) [below of=1] {3};
|
||||
\node[main] (4) [below of=2] {4};
|
||||
\draw (1) -- (2);
|
||||
\draw (1) -- (3);
|
||||
\draw (3) -- (4);
|
||||
\draw (2) -- (4);
|
||||
|
||||
% Directed graph
|
||||
\node[main] (5) [right of=2, xshift=2cm] {A};
|
||||
\node[main] (6) [right of=5] {B};
|
||||
\node[main] (7) [below of=5] {C};
|
||||
\node[main] (8) [below of=6] {D};
|
||||
\draw[->] (5) -- (6);
|
||||
\draw[->] (5) -- (7);
|
||||
\draw[->] (7) -- (8);
|
||||
\draw[->] (6) -- (8);
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
\end{example}
|
||||
@@ -0,0 +1,67 @@
|
||||
\newpage
|
||||
\subsection{Matrix Multiplication}
|
||||
\subsubsection{Strassen's Algorithm}
|
||||
\begin{definition}[]{Strassen’s Algorithm}
|
||||
The \textbf{Strassen’s Algorithm} is an efficient algorithm for matrix multiplication, reducing the asymptotic complexity compared to the standard method.
|
||||
\end{definition}
|
||||
|
||||
\begin{properties}[]{Characteristics of Strassen’s Algorithm}
|
||||
\begin{itemize}
|
||||
\item \textbf{Standard Multiplication:} Requires \tco{n^3} time for two $n \times n$ matrices.
|
||||
\item \textbf{Strassen’s Approach:} Reduces the complexity to \tco{n^{\log_2 7}} (approximately \tco{n^{2.81}}).
|
||||
\item \textbf{Idea:} Uses divide-and-conquer to reduce the number of scalar multiplications from $8$ to $7$ in each recursive step.
|
||||
\item Useful for applications involving large matrix multiplications.
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
\begin{usage}[]{Strassen's Algorithm}
|
||||
Strassen's algorithm is used for matrix multiplication, reducing the computational complexity from \(O(n^3)\) to approximately \(O(n^{2.81})\).
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Divide Matrices:}
|
||||
\begin{itemize}
|
||||
\item Split the input matrices \(A\) and \(B\) into four submatrices each:
|
||||
\[
|
||||
A = \begin{bmatrix} A_{11} & A_{12} \\ A_{21} & A_{22} \end{bmatrix}, \quad
|
||||
B = \begin{bmatrix} B_{11} & B_{12} \\ B_{21} & B_{22} \end{bmatrix}
|
||||
\]
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Compute 7 Products:}
|
||||
\begin{itemize}
|
||||
\item Calculate seven intermediate products using combinations of the submatrices:
|
||||
\begin{align*}
|
||||
M_1 & = (A_{11} + A_{22})(B_{11} + B_{22}) \\
|
||||
M_2 & = (A_{21} + A_{22})B_{11} \\
|
||||
M_3 & = A_{11}(B_{12} - B_{22}) \\
|
||||
M_4 & = A_{22}(B_{21} - B_{11}) \\
|
||||
M_5 & = (A_{11} + A_{12})B_{22} \\
|
||||
M_6 & = (A_{21} - A_{11})(B_{11} + B_{12}) \\
|
||||
M_7 & = (A_{12} - A_{22})(B_{21} + B_{22})
|
||||
\end{align*}
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Combine Results:}
|
||||
\begin{itemize}
|
||||
\item Use the intermediate products to compute the submatrices of the result \(C\):
|
||||
\[
|
||||
C_{11} = M_1 + M_4 - M_5 + M_7, \quad
|
||||
C_{12} = M_3 + M_5
|
||||
\]
|
||||
\[
|
||||
C_{21} = M_2 + M_4, \quad
|
||||
C_{22} = M_1 - M_2 + M_3 + M_6
|
||||
\]
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Repeat Recursively:}
|
||||
\begin{itemize}
|
||||
\item If the submatrices are larger than a certain threshold, repeat the process recursively.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{End:}
|
||||
\begin{itemize}
|
||||
\item The resulting matrix \(C\) is the product of \(A\) and \(B\).
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
\end{usage}
|
||||
@@ -0,0 +1,113 @@
|
||||
\newpage
|
||||
\subsubsection{Boruvka's algorithm}
|
||||
\begin{definition}[]{Definition of Borůvka's Algorithm}
|
||||
Borůvka's Algorithm is a greedy algorithm for finding the Minimum Spanning Tree (MST) of a connected, weighted graph. It repeatedly selects the smallest edge from each connected component and adds it to the MST, merging the components until only one component remains.
|
||||
\end{definition}
|
||||
|
||||
\begin{properties}[]{Characteristics and Performance of Borůvka's Algorithm}
|
||||
\begin{itemize}
|
||||
\item \textbf{Graph Type:} Works on undirected, weighted graphs.
|
||||
\item \textbf{Approach:} Greedy, component-centric.
|
||||
\item \textbf{Time Complexity:} \tct{(|V| + |E|) \log(|V|)}.
|
||||
\item \textbf{Space Complexity:} Depends on the graph representation, typically \tct{E + V}.
|
||||
\item \textbf{Limitations:} Efficient for parallel implementations but less commonly used in practice compared to Kruskal's and Prim's.
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Borůvka's Algorithm}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure{Boruvka}{$G = (V, E)$}
|
||||
\State Initialize a forest $F$ with each vertex as a separate component.
|
||||
\State Initialize an empty MST $T$.
|
||||
\While{the number of components in $F > 1$}
|
||||
\State Initialize an empty set $minEdges$.
|
||||
\For{each component $C$ in $F$}
|
||||
\State Find the smallest edge $(u, v)$ such that $u \in C$ and $v \notin C$.
|
||||
\State Add $(u, v)$ to $minEdges$.
|
||||
\EndFor
|
||||
\For{each edge $(u, v)$ in $minEdges$}
|
||||
\If{$u$ and $v$ are in different components in $F$}
|
||||
\State Add $(u, v)$ to $T$.
|
||||
\State Merge the components containing $u$ and $v$ in $F$.
|
||||
\EndIf
|
||||
\EndFor
|
||||
\EndWhile
|
||||
\State \Return $T$.
|
||||
\EndProcedure
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
\begin{usage}[]{Borůvka's Algorithm}
|
||||
Borůvka's algorithm finds the Minimum Spanning Tree (MST) by repeatedly finding the smallest outgoing edge from each connected component.
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Initialize:}
|
||||
\begin{itemize}
|
||||
\item Assign each vertex to its own component.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Find Smallest Edges:}
|
||||
\begin{itemize}
|
||||
\item For each component, find the smallest outgoing edge. After combination, the other vertex will only be evaluated if it has an even lower weight edge outgoing from it.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Merge Components:}
|
||||
\begin{itemize}
|
||||
\item Add the selected edges to the MST.
|
||||
\item Merge the connected components of the graph.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Repeat:}
|
||||
\begin{itemize}
|
||||
\item Repeat steps 2-3 until only one component remains (all vertices are connected).
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{End:}
|
||||
\begin{itemize}
|
||||
\item The MST is complete, and all selected edges form a connected acyclic graph.
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
\end{usage}
|
||||
|
||||
|
||||
|
||||
% \newpage
|
||||
% \subsection{Example: Electrification of Möhrens}
|
||||
% \begin{figure*}[ht]
|
||||
% \centering
|
||||
% \begin{tikzpicture}
|
||||
% \tikzset{enclosed/.style={draw, circle, inner sep=0pt, minimum size =.5cm, circle}};
|
||||
% \node[enclosed, label={center: $\lightning$}] (power) at (0, 0) {};
|
||||
% \node[enclosed, label={center: A}] (A) at (-1, 1) {};
|
||||
% \node[enclosed, label={center: B}] (B) at (-1, 0) {};
|
||||
% \node[enclosed, label={center: C}] (C) at (-1, -1) {};
|
||||
% \node[enclosed, label={center: D}] (D) at (1, 1) {};
|
||||
% \node[enclosed, label={center: E}] (E) at (1, 0) {};
|
||||
% \node[enclosed, label={center: F}] (F) at (1, -1) {};
|
||||
%
|
||||
% \draw (A) -- node[left] {\scriptsize 3} ++ (B);
|
||||
% \draw (B) -- node[left] {\scriptsize 7} ++ (C);
|
||||
%
|
||||
% \draw (D) -- node[right] {\scriptsize 30} ++ (E);
|
||||
% \draw (E) -- node[right] {\scriptsize 25} ++ (F);
|
||||
% \draw plot[smooth] coordinates {(C) (1.5, -1.5) (1.5, 0.8) (D)};
|
||||
% \node[label={\scriptsize 20}] at (1.8, -1.8) {};
|
||||
%
|
||||
%
|
||||
% \draw (A) -- node[right] {\scriptsize 10} ++ (power);
|
||||
% \draw (B) -- node[above,yshift=-0.1cm] {\scriptsize 5} ++ (power);
|
||||
% \draw (C) -- node[right] {\scriptsize 15} ++ (power);
|
||||
% \draw (D) -- node[left] {\scriptsize 40} ++ (power);
|
||||
% \draw (E) -- node[above,yshift=-0.1cm] {\scriptsize 0} ++ (power);
|
||||
% \draw (F) -- node[left] {\scriptsize 35} ++ (power);
|
||||
% \end{tikzpicture}
|
||||
% \end{figure*}
|
||||
%
|
||||
% \fhlc{Aquamarine}{Goal:} Find sub-graph for which the weights are minimal.
|
||||
%
|
||||
% $G = (V, E)$ is non-directed, connected.
|
||||
%
|
||||
% \fhlc{lightgray}{Weights of edges:} $\{w(e)\}\rvert_{e \in E}$ (non-negative)\\[0.2cm]
|
||||
% \fhlc{lightgray}{Spanning edges $A\subseteq E$} Graph $(V, A)$ is connected\\[0.2cm]
|
||||
% \fhlc{lightgray}{Weight:} $w(A) := \sum_{e \in A} w(e)$\\[0.2cm]
|
||||
@@ -0,0 +1,134 @@
|
||||
\newpage
|
||||
\subsubsection{Kruskal's algorithm}
|
||||
\begin{definition}[]{Kruskal's Algorithm}
|
||||
Kruskal's Algorithm is a greedy algorithm for finding the Minimum Spanning Tree (MST) of a connected, weighted graph. It sorts all the edges by weight and adds them to the MST in order of increasing weight, provided they do not form a cycle with the edges already included.
|
||||
\end{definition}
|
||||
|
||||
\begin{properties}[]{Characteristics and Performance}
|
||||
\begin{itemize}
|
||||
\item \textbf{Graph Type:} Works on undirected, weighted graphs.
|
||||
\item \textbf{Approach:} Greedy, edge-centric.
|
||||
\item \textbf{Time Complexity:} \tco{|E| \log (|E|)} (for sort), \tco{|V| \log(|V|)} (for union find data structure).\\
|
||||
\timecomplexity \tco{|E| \log(|E|) + |V| \log(|V|)}
|
||||
\item \textbf{Space Complexity:} Depends on the graph representation, typically \tct{E + V}.
|
||||
\item \textbf{Limitations:} Requires sorting of edges, which can dominate runtime.
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Kruskal's Algorithm}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure{Kruskal}{$G = (V, E)$}
|
||||
\State Sort all edges $E$ in non-decreasing order of weight.
|
||||
\State Initialize an empty MST $T$.
|
||||
\State Initialize a disjoint-set data structure for $V$.
|
||||
\For{each edge $(u, v)$ in $E$ (in sorted order)}
|
||||
\If{$u$ and $v$ belong to different components in the disjoint set}
|
||||
\State Add $(u, v)$ to $T$.
|
||||
\State Union the sets containing $u$ and $v$.
|
||||
\EndIf
|
||||
\EndFor
|
||||
\State \Return $T$.
|
||||
\EndProcedure
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
\begin{usage}[]{Kruskal's Algorithm}
|
||||
Kruskal's algorithm finds the Minimum Spanning Tree (MST) by sorting edges and adding them to the MST, provided they don't form a cycle.
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Sort Edges:}
|
||||
\begin{itemize}
|
||||
\item Sort all edges in ascending order by their weights.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Initialize Disjoint Sets (union find):}
|
||||
\begin{itemize}
|
||||
\item Assign each vertex to its own disjoint set to track connected components.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Iterate Over Edges:}
|
||||
\begin{itemize}
|
||||
\item For each edge in the sorted list:
|
||||
\begin{itemize}
|
||||
\item Check if the edge connects vertices from different sets.
|
||||
\item If it does, add the edge to the MST and merge the sets.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Stop When Done:}
|
||||
\begin{itemize}
|
||||
\item Stop when the MST contains \(n-1\) edges (for a graph with \(n\) vertices).
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{End:}
|
||||
\begin{itemize}
|
||||
\item The MST is complete, and all selected edges form a connected acyclic graph.
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
\end{usage}
|
||||
|
||||
|
||||
\newpage
|
||||
\fhlc{Aquamarine}{Union-Find}
|
||||
\begin{usage}[]{Union-Find Data Structure - Step-by-Step Execution}
|
||||
The Union-Find data structure efficiently supports two primary operations for disjoint sets:
|
||||
\begin{itemize}
|
||||
\item \textbf{Union:} Merge two sets into one.
|
||||
\item \textbf{Find:} Identify the representative (or root) of the set containing a given element.
|
||||
\end{itemize}
|
||||
|
||||
\textbf{Steps for Using the Union-Find Data Structure:}
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Initialization:}
|
||||
\begin{itemize}
|
||||
\item Create an array \(parent\), where \(parent[i] = i\), indicating that each element is its own parent (a singleton set).
|
||||
\item Optionally, maintain a \(rank\) array to track the rank (or size) of each set for optimization.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Find Operation:}
|
||||
\begin{itemize}
|
||||
\item To find the representative (or root) of a set containing element \(x\):
|
||||
\begin{enumerate}
|
||||
\item Follow the \(parent\) array recursively until \(parent[x] = x\).
|
||||
\item Apply \textbf{path compression} by updating \(parent[x]\) directly to the root to flatten the tree structure:
|
||||
\[
|
||||
parent[x] = \text{Find}(parent[x])
|
||||
\]
|
||||
\end{enumerate}
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Union Operation:}
|
||||
\begin{itemize}
|
||||
\item To merge the sets containing \(x\) and \(y\):
|
||||
\begin{enumerate}
|
||||
\item Find the roots of \(x\) and \(y\) using the Find operation.
|
||||
\item Compare their ranks:
|
||||
\begin{itemize}
|
||||
\item Attach the smaller tree under the larger tree to keep the structure shallow.
|
||||
\item If ranks are equal, arbitrarily choose one as the root and increment its rank.
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Optimization Techniques:}
|
||||
\begin{itemize}
|
||||
\item \textbf{Path Compression:} Flattens the tree during Find operations, reducing the time complexity.
|
||||
\item \textbf{Union by Rank/Size:} Ensures smaller trees are always attached under larger trees, maintaining a logarithmic depth.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{End:}
|
||||
\begin{itemize}
|
||||
\item After performing Find and Union operations, the Union-Find structure can determine connectivity between elements or group them into distinct sets efficiently.
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
\end{usage}
|
||||
|
||||
\begin{properties}[]{Performance}
|
||||
\begin{itemize}
|
||||
\item \textsc{make}$(V)$: Initialize data structure \tco{n}
|
||||
\item \textsc{same}$(u, v)$: Check if two components belong to the same set \tco{1} or \tco{n}, depending on if the representant is stored in an array or not
|
||||
\item \textsc{union}$(u, v)$: Combine two sets, \tco{\log(n)}, in Kruskal we call this \tco{n} times, so total number (amortised) is \tco{n \log(n)}
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
@@ -0,0 +1,83 @@
|
||||
\newpage
|
||||
\subsection{MST}
|
||||
\subsubsection{Prim's algorithm}
|
||||
\begin{definition}[]{Definition of Prim's Algorithm}
|
||||
Prim's Algorithm is a greedy algorithm for finding the Minimum Spanning Tree (MST) of a connected, weighted graph.
|
||||
It starts with an arbitrary node and iteratively adds the smallest edge connecting a vertex in the MST to a vertex outside the MST until all vertices are included.
|
||||
\end{definition}
|
||||
|
||||
\begin{properties}[]{Characteristics and Performance of Prim's Algorithm}
|
||||
\begin{itemize}
|
||||
\item \textbf{Graph Type:} Works on undirected, weighted graphs.
|
||||
\item \textbf{Approach:} Greedy, vertex-centric.
|
||||
\item \textbf{Time Complexity:}
|
||||
\begin{itemize}
|
||||
\item With an adjacency matrix: \tct{V^2}.
|
||||
\item With a priority queue and adjacency list: \tct{(|V| + |E|) \log(|V|)}.
|
||||
\end{itemize}
|
||||
\item \textbf{Space Complexity:} Depends on the graph representation, typically \tct{E + V}.
|
||||
\item \textbf{Limitations:} Less efficient than Kruskal's for sparse graphs using adjacency matrices.
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Prim's Algorithm}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure{Prim}{$G = (V, E)$, $start$}
|
||||
\State Initialize a priority queue $Q$.
|
||||
\State Initialize $key[v] \gets \infty$ for all $v \in V$, except $key[start] \gets 0$.
|
||||
\State Initialize an empty MST $T$.
|
||||
\State Add all vertices to $Q$ with their key values.
|
||||
\While{$Q$ is not empty}
|
||||
\State $u \gets$ ExtractMin($Q$).
|
||||
\State Add $u$ to $T$.
|
||||
\For{each $(u, v)$ in $E$}
|
||||
\If{$v$ is in $Q$ and weight($u, v$) $< key[v]$}
|
||||
\State $key[v] \gets$ weight($u, v$).
|
||||
\State Update $Q$ with $key[v]$.
|
||||
\EndIf
|
||||
\EndFor
|
||||
\EndWhile
|
||||
\State \Return $T$.
|
||||
\EndProcedure
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
\begin{usage}[]{Prim's Algorithm}
|
||||
Prim's algorithm is used to find the Minimum Spanning Tree (MST) of a graph. It starts with a single node and grows the MST by adding the smallest edge that connects a vertex in the MST to a vertex outside it.
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Initialize:}
|
||||
\begin{itemize}
|
||||
\item Pick any starting vertex as part of the MST.
|
||||
\item Mark the vertex as visited and add it to the MST.
|
||||
\item Initialize a priority queue to store edges by their weight.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Explore Edges:}
|
||||
\begin{itemize}
|
||||
\item Add all edges from the visited vertex to the priority queue.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Pick the Smallest Edge:}
|
||||
\begin{itemize}
|
||||
\item Choose the smallest-weight edge from the priority queue that connects a visited vertex to an unvisited vertex.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Add the New Vertex:}
|
||||
\begin{itemize}
|
||||
\item Mark the vertex connected by the chosen edge as visited.
|
||||
\item Add the edge and the vertex to the MST.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Repeat:}
|
||||
\begin{itemize}
|
||||
\item Repeat steps 2-4 until all vertices are part of the MST or no more edges are available.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{End:}
|
||||
\begin{itemize}
|
||||
\item The MST is complete when all vertices are visited, and the selected edges form a connected acyclic graph.
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
\end{usage}
|
||||
@@ -0,0 +1,66 @@
|
||||
\newpage
|
||||
\subsection{Paths, Walks, Cycles}
|
||||
\begin{definition}[]{Paths, Walks, and Cycles in Graphs}
|
||||
\begin{itemize}
|
||||
\item \textbf{Walk:} A sequence of vertices and edges in a graph, where each edge connects consecutive vertices in the sequence. Vertices and edges may repeat.
|
||||
\item \textbf{Path:} A walk with no repeated vertices. In a directed graph, the edges must respect the direction.
|
||||
\item \textbf{Cycle:} A path that starts and ends at the same vertex. For a simple cycle, all vertices (except the start/end vertex) and edges are distinct.
|
||||
\item \textbf{Eulerian Walk:} A walk that traverses every edge of a graph exactly once.
|
||||
\item \textbf{Closed Eulerian Walk (Eulerian Cycle):} An Eulerian walk that starts and ends at the same vertex.
|
||||
\item \textbf{Hamiltonian Path:} A path that visits each vertex of a graph exactly once. Edges may or may not repeat.
|
||||
\item \textbf{Hamiltonian Cycle:} A Hamiltonian path that starts and ends at the same vertex.
|
||||
\end{itemize}
|
||||
\end{definition}
|
||||
|
||||
\begin{properties}[]{Eulerian Graphs}
|
||||
\begin{itemize}
|
||||
\item \textbf{Undirected Graph:}
|
||||
\begin{itemize}
|
||||
\item A graph has an Eulerian walk if it has exactly two vertices of odd degree (necessary condition).
|
||||
\item A graph has a closed Eulerian walk if all vertices have even degree (necessary condition).
|
||||
\end{itemize}
|
||||
\item \textbf{Directed Graph:}
|
||||
\begin{itemize}
|
||||
\item A graph has an Eulerian walk if at most one vertex has \textit{in-degree} one greater than its \textit{out-degree}, and at most one vertex has \textit{out-degree} one greater than its \textit{in-degree}. All other vertices must have equal in-degree and out-degree.
|
||||
\item A graph has a closed Eulerian walk if every vertex has equal in-degree and out-degree.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
\begin{properties}[]{Hamiltonian Graphs}
|
||||
\begin{itemize}
|
||||
\item Unlike Eulerian walks, there is no simple necessary or sufficient condition for the existence of Hamiltonian paths or cycles.
|
||||
\item A graph with $n$ vertices is Hamiltonian if every vertex has a degree of at least $\lceil n / 2 \rceil$ (Dirac's Theorem, sufficient condition).
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
\begin{example}[]{Eulerian and Hamiltonian}
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[node distance=1.5cm, main/.style={circle, draw, fill=blue!20, minimum size=10mm, inner sep=0pt}] % Eulerian graph example
|
||||
\node[main] (1) {1};
|
||||
\node[main] (2) [above right of=1] {2};
|
||||
\node[main] (3) [below right of=1] {3};
|
||||
\node[main] (4) [right of=3] {4};
|
||||
\node[main] (5) [above right of=4] {5};
|
||||
\draw (1) -- (2) -- (5) -- (4) -- (3) -- (1) -- (4) -- (2);
|
||||
\draw (2) -- (3);
|
||||
|
||||
% Hamiltonian graph example
|
||||
\node[main] (6) [right of=5, xshift=3cm] {A};
|
||||
\node[main] (7) [above right of=6] {B};
|
||||
\node[main] (8) [below right of=6] {C};
|
||||
\node[main] (9) [right of=7] {D};
|
||||
\node[main] (10) [right of=8] {E};
|
||||
\draw (6) -- (7) -- (9) -- (10) -- (8) -- (6);
|
||||
\draw (6) -- (10);
|
||||
\draw (7) -- (8);
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
\end{example}
|
||||
|
||||
\begin{remarks}[]{Key Differences Between Eulerian and Hamiltonian Concepts}
|
||||
\begin{itemize}
|
||||
\item Eulerian paths are concerned with traversing every \textbf{edge} exactly once, while Hamiltonian paths are about visiting every \textbf{vertex} exactly once.
|
||||
\item Eulerian properties depend on the degree of vertices, whereas Hamiltonian properties depend on overall vertex connectivity.
|
||||
\end{itemize}
|
||||
\end{remarks}
|
||||
@@ -0,0 +1,169 @@
|
||||
\newpage
|
||||
\subsection{Shortest path}
|
||||
\subsubsection{Dijkstra's Algorithm}
|
||||
\begin{definition}[]{Dijkstra's Algorithm}
|
||||
\textbf{Dijkstra's Algorithm} is a graph search algorithm that finds the shortest paths from a source vertex to all other vertices in a graph with non-negative edge weights.
|
||||
\end{definition}
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Dijkstra's Algorithm}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure{Dijkstra}{$G = (V, E), s$} \Comment{$s$ is the source vertex}
|
||||
\State Initialize distances: $d[v] \gets \infty \; \forall v \in V, d[s] \gets 0$
|
||||
\State Initialize priority queue $Q$ with all vertices, priority set to $\infty$
|
||||
\While{$Q$ is not empty}
|
||||
\State $u \gets \textbf{Extract-Min}(Q)$
|
||||
\For{each neighbor $v$ of $u$}
|
||||
\If{$d[u] + w(u, v) < d[v]$} \Comment{If weight through current vertex is lower, update}
|
||||
\State $d[v] \gets d[u] + w(u, v)$
|
||||
\State Update $Q$ with new distance of $v$
|
||||
\EndIf
|
||||
\EndFor
|
||||
\EndWhile
|
||||
\State \textbf{Return} distances $d$
|
||||
\EndProcedure
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
\begin{properties}[]{Characteristics of Dijkstra's Algorithm}
|
||||
\begin{itemize}
|
||||
\item \textbf{Time Complexity:}
|
||||
\begin{itemize}
|
||||
\item \tco{|V|^2} for a simple implementation.
|
||||
\item \tco{(|V| + |E|) \log |V|} using a priority queue.
|
||||
\end{itemize}
|
||||
\item Only works with non-negative edge weights.
|
||||
\item Greedy algorithm that processes vertices in increasing order of distance.
|
||||
\item Common applications include navigation systems and network routing.
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
\begin{usage}[]{Dijkstra's Algorithm}
|
||||
Dijkstra's algorithm finds the shortest path from a source vertex to all other vertices in a weighted graph (non-negative weights).
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Initialize:}
|
||||
\begin{itemize}
|
||||
\item Set the distance to the source vertex as 0 and to all other vertices as infinity.
|
||||
\item Mark all vertices as unvisited.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Start from Source:}
|
||||
\begin{itemize}
|
||||
\item Select the unvisited vertex with the smallest tentative distance.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Update Distances:}
|
||||
\begin{itemize}
|
||||
\item For each unvisited neighbor of the current vertex:
|
||||
\begin{itemize}
|
||||
\item Calculate the tentative distance through the current vertex.
|
||||
\item If the calculated distance is smaller than the current distance, update it.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Mark as Visited:}
|
||||
\begin{itemize}
|
||||
\item Mark the current vertex as visited. Once visited, it will not be revisited.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Repeat:}
|
||||
\begin{itemize}
|
||||
\item Repeat steps 2-4 until all vertices are visited or the shortest path to all vertices is determined.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{End:}
|
||||
\begin{itemize}
|
||||
\item The algorithm completes when all vertices are visited or when the shortest paths to all reachable vertices are found.
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
\end{usage}
|
||||
|
||||
|
||||
|
||||
|
||||
\newpage
|
||||
\subsubsection{Bellman-Ford Algorithm}
|
||||
\begin{definition}[]{Bellman-Ford Algorithm}
|
||||
The \textbf{Bellman-Ford Algorithm} computes shortest paths from a source vertex to all other vertices, allowing for graphs with negative edge weights.
|
||||
\end{definition}
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Bellman-Ford Algorithm}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure{Bellman-Ford}{$G = (V, E), s$} \Comment{$s$ is the source vertex}
|
||||
\State Initialize distances: $d[v] \gets \infty \; \forall v \in V, d[s] \gets 0$
|
||||
\For{$i \gets 1$ to $|V| - 1$} \Comment{Relax all edges $|V| - 1$ times}
|
||||
\For{each edge $(u, v, w(u, v)) \in E$}
|
||||
\If{$d[u] + w(u, v) < d[v]$}
|
||||
\State $d[v] \gets d[u] + w(u, v)$
|
||||
\EndIf
|
||||
\EndFor
|
||||
\EndFor
|
||||
\For{each edge $(u, v, w(u, v)) \in E$} \Comment{Check for negative-weight cycles}
|
||||
\If{$d[u] + w(u, v) < d[v]$}
|
||||
\State \textbf{Report Negative Cycle}
|
||||
\EndIf
|
||||
\EndFor
|
||||
\State \Return distances $d$
|
||||
\EndProcedure
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
\begin{properties}[]{Characteristics of Bellman-Ford Algorithm}
|
||||
\begin{itemize}
|
||||
\item \textbf{Time Complexity:} \tco{|V| \cdot |E|}.
|
||||
\item Can handle graphs with negative edge weights but not graphs with negative weight cycles.
|
||||
\item Used for:
|
||||
\begin{itemize}
|
||||
\item Detecting negative weight cycles.
|
||||
\item Computing shortest paths in graphs where Dijkstra’s algorithm is not applicable.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{properties}
|
||||
|
||||
\begin{usage}[]{Bellman-Ford Algorithm}
|
||||
The Bellman-Ford algorithm finds the shortest path from a source vertex to all other vertices in a weighted graph (handles negative weights).
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Initialize:}
|
||||
\begin{itemize}
|
||||
\item Set the distance to the source vertex as 0 and to all other vertices as infinity.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Relax Edges:}
|
||||
\begin{itemize}
|
||||
\item Repeat for \(V-1\) iterations (where \(V\) is the number of vertices):
|
||||
\begin{itemize}
|
||||
\item For each edge, update the distance to its destination vertex if the distance through the edge is smaller than the current distance.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{Check for Negative Cycles:}
|
||||
\begin{itemize}
|
||||
\item Check all edges to see if a shorter path can still be found. If so, the graph contains a negative-weight cycle.
|
||||
\end{itemize}
|
||||
|
||||
\item \textbf{End:}
|
||||
\begin{itemize}
|
||||
\item If no negative-weight cycle is found, the algorithm outputs the shortest paths.
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
\end{usage}
|
||||
|
||||
|
||||
|
||||
\begin{properties}[]{Comparison of Dijkstra and Bellman-Ford}
|
||||
\begin{center}
|
||||
\begin{tabular}{lcc}
|
||||
\toprule
|
||||
\textbf{Feature} & \textbf{Dijkstra's Algorithm} & \textbf{Bellman-Ford Algorithm} \\
|
||||
\midrule
|
||||
Handles Negative Weights & No & Yes \\
|
||||
Detects Negative Cycles & No & Yes \\
|
||||
Time Complexity & \tco{(|V| + |E|) \log |V|} & \tco{|V| \cdot |E|} \\
|
||||
Algorithm Type & Greedy & Dynamic Programming \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
\end{properties}
|
||||
Reference in New Issue
Block a user