Module 0310: Graph search algorithms

About this module

What is a graph?

A graph is a 2-tuple, $G=(V,E)$, where $V$ is a set of vertices, and $E$ is a set of edges. There is little restriction of the set of vertices. However, the nature of the set of edges depends on whether a graph is directed or not.

In the case of a directed graph, or a digraph in short, $E\subseteq V \times V$. This means that each edge is a two-tuple where the first item (called the tail) and the second item (called the head) are both elements of $V$. Recall that ordering is significant in a tuple. An edge of a digraph is usually drawn as an arrow going from the tail (first item) to the head (second item).

A graph may be un-directed. Such a graph can be seen as a special case of a digraph where $(a,b)\in E \Leftrightarrow (b,a) \in E$.

Terms

A path $p$ in a graph $G=(V,E)$ is a tuple of vertices. Edges from $E$ must lead from one vertex to the next. In other words,

$\forall i \in \mathbb{N}(i \le |p|-2 \Rightarrow (p[i],p[i+1]) \in E)$

Furthermore, a path cannot contain duplicates of a vertex.

In many graphs, a distance function $d: E \rightarrow \mathbb{R}^*$ maps edges of a graph to real number values. In most cases, the distance of an edge cannot be negative, hence the use of $\mathbb{R}^*$ to denote non-negative real numbers.

Dijkstra’s algorithm

Dijkstra’s algorithm finds the shortest path from all vertices in a graph to a particular set of “destination” vertices. The following is the pseudocode:

The A* Algorithm

The A* (pronounced a-star) algorithm is another shortest path finding algorithm. It differs from Dijkstra’s algorithm in that the A* algorithm utilizes a “heuristic” function to guide the search for the shortest path. A heuristic function for a graph $G=(V,E)$ is often in the form of $h:(V\times V)\rightarrow \mathbb{R}^*$. It is a quick-to-compute function that estimates the actual shortest distance between two vertices. Because the A* algorithm only has one destination $x$, the heuristic function only needs to be $h:(V \times \{x\}) \rightarrow \mathbb{R}^*$ because there is no need to know the heuristic between a vertex and any non-destination vertex.

In order for the A* algorithm to function, the heuristic function has to be admissible. This means that if $L:(V \times V)\rightarrow \mathbb{R}^*$ represents the actual length of the shortest path between two vertices, then $\forall v,w\in V(h(v,w) \leq L(v,w))$. In short, the heuristic function must be an underestimate of the actual length of the shortest path.

Note that one always define $h(v,w)=0$ as an underestimating heuristic. However, this means the search for the shortest path is not any more guided than Dijkstra’s algorithm.

The A* algorithm differs from Dijkstra’s algorithm in an important way. While Dijkstra’s algorithm explores “backwards” from destination vertices, The A* algorithm explores “forward” from a start vertex. The following presents the pseudocode of the A* algorithm:

Graph Examples

For Dijkstra’s algorithm

flowchart LR
a(a)
b(b)
c(c)
d(d)
e(((e)))
f(((f)))
a-- 10 -->e
a== 5 ==>b
c-- 8 -->f
b== 2 ==>e
b-- 4 -->f
c== 4 ==>d
d-- 6 -->e
d== 2 ==>f
b-- 4 -->a
f-- 2 -->d

For the A* algorithm

flowchart LR
a(a)
b(b)
c(c)
d(d)
e(e)
f((f))
e-- 5 -->a
a-- 8 -->b
a-- 5 -->c
a-- 2 -->d
d-- 20 -->f
c-- 10 -->f
b-- 2 -->f
d-- 2 -->c
c-- 2 -->b
e-. 13 .->f
a-. 5 .-> f
b-. 2 .-> f
c-. 1 .-> f
d-. 0 .-> f
f-. 0 .-> f