You are on page 1of 176

Design & Analysis of Algorithms

Lecture#10
Graph Introduction,
BFT, DFT,
MST,
Shortest Path
Lecture Contents
Graph
Graph Terminologies
Graph Representations (Adjacency Matrix, Adjacency Link List)
Graph Traversals (Depth First, Breadth First)
Spanning Tree
Minimum Spanning Tree
 Kruskalls’ Algorithm
 Prim’s Algorithm

Shortest Path
 Dijkstra’s Algorithm
 Bellman Ford Algorithm
 A* Algorithm
Graph
A graph G (V, X) consists of two sets V & X. V is a set of
vertices & X is a set of Edges
Every edge e ϵ X joins two vertices in V
Graph G = (V, X)
where V = Set of vertices
AND X = set of edges
AND X  V x V
Example:
G = (V, X)
V = {A, B, C, D, E, F}
X = {(A,B), (A,C), (B,D), (D,E), (D,F), (C,E), (C, F), (E,F)}
Directed Graph (Digraph)
A directed graph is a graph in which all edges are directed.
Directed graph is also called a digraph.
G = (V, E)
V = {A, B, C, D, F, G}
E = {(A,B), (A,C), (B,D), (D,E), (D,F), (C,E), (E,F), (F,C)}
Undirected Graph
A undirected graph is a graph in which all edges are bidirectional.
In an undirected graph G(V,E),
∀e ϵ E
e1 (u, v) = e2 (u, v)
Connected Graph
A graph is connected if there is path between every two nodes of
that graph.
Complete Graph
•A graph is complete if there is edge between every two nodes of
that graph.
Total number of edges in complete graph are given as:
Degree, In Degree, Out Degree
Degree:
Number of edges connecting a vertex is called the
degree of node.
Degree of vertex A is 6
In Degree:
Number of edges pointing into a vertex is called its in
degree
In Degree of vertex A is 2
Out Degree:
Number of edges going out of a vertex is called its out
degree
Out Degree of vertex A is 4
Adjacency
Two nodes are said to be adjacent if they are connected through an edge.
In the example below nodes B&C, C&D, D&E are adjacent to each other.

Adjacent Nodes
Weighted Graph
A graph in which every edge has some weight
(numeric value) associated with it.
It refers to the effort while going from one vertex to
other using this edge
Weighted Graph
Unweighted Graph
A graph having no weight value associated with
any of its edge is called an unweighted graph

Unweighted Graph
Reachable Node
A node is reachable from another node if there exists a path
between them.

Path exists between A & E


Multigraph, Pseudo Graph Multigraph

Multigraph
A graph is said to be multigraph if it allows more
than one paths between two nodes
Pseudo Graph
A graph is pseudo graph if it allows if it allows self
loops

Pseudo Graph
Reachable Node
A node is reachable from another node if
there exists a path between them.

For given graph paths exist between:


A&B Path exists between A & E
A&D
A&F
B&F
C&F
Path
A path of length k is sequence of v1, v2, v3, …., vk of vertices such
that (vi, vi+1) for i = 0, 1, 2, …, k-1 is an edge of graph.

1. ABCD is a path
2. ABD is not a path
Cycle
A cycle is a path starting and ending at same vertex

ABCA makes a cycle in this


graph
Hamiltonian Cycle
A Hamiltonian Cycle is a cycle in an undirected graph which
visits every vertex of graph and also returns to starting vertex.

Hamiltonian Cycle:
A, B, C, D, E, F, G, H, A
Eulerian Cycle
An Eulerian Cycle of a connected directed / undirected graph is a cycle
that traverses each edge of a graph exactly once. There may be one
vertex that is visited more than once.

Eulerian Cycle:
A, B, C, D, E, F, C, G back to A
Subgraph
A subgraph H of graph G is a graph that has its vertices and edges
as subsets of vertices and edges of G respectively.

Graph G
V = {A, B, C, D, E, F, G}
Subgraph H Edges={(A,B), (A,G), (B,C), (B, G), (C,D), (C,F), (C,G),
V = {A, B, C, G} (D,E), (D,F), (E,F)}
Edges={(A,B), (A,G), (B,C), (B, G), (C,G)}
Tree
A connected graph without any cycles is call a tree graph or simply a tree.
For a tree graph, there is a unique path between every two nodes of the
graph

Tree
Graph Representation
Graphs are represented through two different ways:
1. Adjacency Matrix
2. Adjacency List
Graph Adjacency Matrix Representation
Say a graph has V={1,2,3,…,n} vertices then graph is represented by
a NXN matrix A such that:
A[i, j] = 1 if there is edge between nodes i & j
= 0 otherwise

Graph G
Graph G 1 2 3 4

1 0 0 1 0
2 0 0 1 1
3 1 1 0 1
4 0 1 1 0

Space Complexity: ϴ|V2|


Graph Adjacency Matrix Representation
Adjacency matrix is dense representation i.e. too much space required for large
number of vertices
Can be very efficient for small graphs
Graph Adjacency List Representation
For each vertex, a list of adjacent vertices (neighbors) is maintained
For the given graph:
Adj[1] = {3}
Adj[2]={3,4}
Adj[3]={1,2,4}
Adj[4]={2,3} Graph G
A possible variation can be to store the list of incoming edges instead of
outgoing edges
Graph Adjacency List Representation
If a graph is directed then sum of lengths of all adjacency lists is equal to the
number of edges in graph
If the graph is undirected then this number is doubled

Adjacency List for G Graph G


Graph Traversals
Graphs are traversed using two different methods:
1. Breadth First Traversal
2. Depth First Traversal
A Typical Graph Traversal
For a connected graph, pick one node as root node and visit all nodes of the
graph in some order
Starting from root we iterate for each node of the graph
During every iteration we visit the node and capture the neighboring nodes of
node in hand
Keep repeating until all nodes are visited
For graphs with disconnected nodes, we may need to visit subgraphs
containing all nodes disconnected with root node separately
Depth First Graph Traversal (Recursive)
proc dfs(G, v) // G is graph, v is a vertex
v.visited = true
list  G.getAdjacencyList(v)
foreach node in list do
if node.visited != true then dfs() was initially called as:
dfs(G, node) dfs(G, A)
endif
next
end proc
Depth First Graph Traversal (Recursive) … Demo
Graph = G
G = (V, X)
V = {A, B, C, D, E, F}
proc dfs(G, v) // G is graph, v is a vertex X = {(A,B), (A, C), (B, D), (C, E),(D, E), (D, F), (E, G)}
v.visited = true
list  G.getAdjacencyList(v)
foreach node in list do Active function call: dfs(G, A)
if node.visited != true then
dfs(G, node)
endif
next
end proc
1. Node A is visited
2. Neighbors of A are being processed now Neighbors list of A: {B, C}
3. Since B is not already visited, dfs(G, B) is called
suspending function dfs(G, A) Visited Nodes = {A}
Depth First Graph Traversal (Recursive) … Demo
Graph = G
proc dfs(G, v) // G is graph, v is a vertex G = (V, X)
V = {A, B, C, D, E, F}
v.visited = true X = {(A,B), (A, C), (B, D), (C, E),(D, E), (D, F), (E, G)}
list  G.getAdjacencyList(v)
foreach node in list do
Active function call: dfs(G, B)
if node.visited != true then
dfs(G, node)
endif
next
end proc

1. Node B is visited Neighbors list of B: {D, A}


2. Neighbors of B are being processed now
3. Since D is not already visited, dfs(G, D) is called
suspending function dfs(G, B) Visited Nodes = {A, B}
Depth First Graph Traversal (Recursive) … Demo
Graph = G
proc dfs(G, v) // G is graph, v is a vertex G = (V, X)
V = {A, B, C, D, E, F}
v.visited = true X = {(A,B), (A, C), (B, D), (C, E),(D, E), (D, F), (E, G)}
list  G.getAdjacencyList(v)
foreach node in list do
Active function call: dfs(G, D)
if node.visited != true then
dfs(G, node)
endif
next
end proc

1. Node D is visited Neighbors list of D: {B, E, F}


2. Neighbors of D are being processed now
3. Since B is already visited, no call to dfs(G, B) is Visited Nodes = {A, B, D}
made. dfs(G, D) continues
Depth First Graph Traversal (Recursive) … Demo
Graph = G
proc dfs(G, v) // G is graph, v is a vertex G = (V, X)
V = {A, B, C, D, E, F}
v.visited = true X = {(A,B), (A, C), (B, D), (C, E),(D, E), (D, F), (E, G)}
list  G.getAdjacencyList(v)
foreach node in list do
Active function call: dfs(G, D)
if node.visited != true then
dfs(G, node)
endif
next
end proc

1. Processing of D neighbors continues Neighbors list of D: {B, E, F}


2. Since E is not already visited, dfs(G, E) is called
suspending function dfs(G, D) Visited Nodes = {A, B, D}
Depth First Graph Traversal (Recursive) … Demo
Graph = G
proc dfs(G, v) // G is graph, v is a vertex G = (V, X)
V = {A, B, C, D, E, F}
v.visited = true X = {(A,B), (A, C), (B, D), (C, E),(D, E), (D, F), (E, G)}
list  G.getAdjacencyList(v)
foreach node in list do
Active function call: dfs(G, E)
if node.visited != true then
dfs(G, node)
endif
next
end proc

1. Node E is visited
2. Processing of E neighbors continues Neighbors list of E: {C, D, F}
3. Since C is not already visited, dfs(G, C) is called Visited Nodes = {A, B, D, E}
suspending function dfs(G, E)
Depth First Graph Traversal (Recursive) … Demo
Graph = G
proc dfs(G, v) // G is graph, v is a vertex G = (V, X)
V = {A, B, C, D, E, F}
v.visited = true X = {(A,B), (A, C), (B, D), (C, E),(D, E), (D, F), (E, G)}
list  G.getAdjacencyList(v)
foreach node in list do
Active function call: dfs(G, C)
if node.visited != true then
dfs(G, node)
endif
next
end proc

1. Node C is visited
2. Processing of C neighbors continues Neighbors list of C: {A, E}
3. Since A is already visited, dfs(G, C) is not called. Visited Nodes = {A, B, D, E, C}
Processing of neighbors continues
Depth First Graph Traversal (Recursive) … Demo
Graph = G
proc dfs(G, v) // G is graph, v is a vertex G = (V, X)
V = {A, B, C, D, E, F}
v.visited = true X = {(A,B), (A, C), (B, D), (C, E),(D, E), (D, F), (E, G)}
list  G.getAdjacencyList(v)
foreach node in list do
Active function call: dfs(G, C)
if node.visited != true then
dfs(G, node)
endif
next
end proc

1. Since E is already visited, dfs(G, E) is not called.


2. All the neighbors of C have been processed Neighbors list of C: {A, E}
3. Call of dfs(G, C) is finished Visited Nodes = {A, B, D, E, C}
4. dfs(G, E) resumes
Depth First Graph Traversal (Recursive) … Demo
Graph = G
proc dfs(G, v) // G is graph, v is a vertex G = (V, X)
V = {A, B, C, D, E, F}
v.visited = true X = {(A,B), (A, C), (B, D), (C, E),(D, E), (D, F), (E, G)}
list  G.getAdjacencyList(v)
foreach node in list do
Active function call: dfs(G, E)
if node.visited != true then
dfs(G, node)
endif
next
end proc

1. dfs(G, E) resumes
2. Since F is not already visited, dfs(G, F) is called Neighbors list of E: {C, D, F}
suspending the execution of dfs(G, E) Visited Nodes = {A, B, D, E, C}
Depth First Graph Traversal (Recursive) … Demo
Graph = G
proc dfs(G, v) // G is graph, v is a vertex G = (V, X)
V = {A, B, C, D, E, F}
v.visited = true X = {(A,B), (A, C), (B, D), (C, E),(D, E), (D, F), (E, G)}
list  G.getAdjacencyList(v)
foreach node in list do
Active function call: dfs(G, F)
if node.visited != true then
dfs(G, node)
endif
next
end proc

1. Node F is visited
2. One can observe that all nodes of G are visited now
3. Since all neighbors of F are already visited, no call to Neighbors list of F: {D, E}
dfs() Visited Nodes = {A, B, D, E, C, F}
4. dfs(G, F) exits giving control back to dfs(G, E)
Depth First Graph Traversal (Recursive) … Demo
proc dfs(G, v) // G is graph, v is a vertex
v.visited = true
list  G.getAdjacencyList(v)
foreach node in list do
if node.visited != true then Visited Nodes = {A, B, D, E, C, F}
dfs(G, node)
endif
next
end proc
1. All the calls to dfs() exit now one by one since
all the nodes in graph are already visited
2. Depth first traversal ends
Depth First Graph Traversal (Iterative)… Demo
proc dfs(G, v) // G is graph, v is a vertex
stack.push(v)
while !stack.empty() do dfs() was initially called as:
v  stack.pop() dfs(G, A)
v.visited  true
A node is pushed to stack
list  G.getAdjacencyList(v)
foreach node in list do
if node.visited != true then
stack.push(node)
endif
next
next
end proc

Since stack is not empty, while loop will execute


Depth First Graph Traversal (Iterative)… Demo

While-loop executes

v=A
v is visited
list = {B, C}
Depth First Graph Traversal (Iterative)… Demo

While-loop executes

Every neighbor of A that is


not already visited, is pushed
to stack
Depth First Graph Traversal (Iterative)… Demo

Since stack is not empty,


While-loop executes

1. Stack is popped v=C


2. C is visited v is visited
3. Its neighbor nodes are list = {A, E}
stored in list
Depth First Graph Traversal (Iterative)… Demo

While-loop executes

Every neighbor of C that is


not already visited, is pushed
to stack
Depth First Graph Traversal (Iterative)… Demo

Since stack is not empty,


While-loop executes

1. Stack is popped v=E


2. E is visited v is visited
3. Its neighbor nodes are stored list = {C, D, F}
in list
Depth First Graph Traversal (Iterative)… Demo

While-loop executes

Every neighbor of E that is


not already visited, is pushed
to stack
Depth First Graph Traversal (Iterative)… Demo

Since stack is not empty,


While-loop executes

1. Stack is popped v=F


2. F is visited v is visited
3. Its neighbor nodes are list = {D, E}
stored in list
Depth First Graph Traversal (Iterative)… Demo
While-loop executes

Every neighbor of F that is


not already visited, is pushed
to stack
Depth First Graph Traversal (Iterative)… Demo

Since stack is not empty,


While-loop executes

1. Stack is popped v=D


2. D is visited v is visited
3. Its neighbor nodes are list = {B, E, F}
stored in list
Depth First Graph Traversal (Iterative)… Demo
While-loop executes

Every neighbor of D that is


not already visited, is pushed
to stack
Depth First Graph Traversal (Iterative)… Demo

Since stack is not empty,


While-loop executes

1. Stack is popped v=B


2. B is visited v is visited
3. Its neighbor nodes are list = {A, D}
stored in list
Depth First Graph Traversal (Iterative)… Demo
While-loop executes

Since all the neighbors


are already visited,
Every neighbor of D that is nothing is pushed onto
not already visited, is pushed stack
to stack
Depth First Graph Traversal (Iterative)… Demo

Since stack is not empty,


While-loop executes

1. Stack is popped v=D


2. D is visited v is visited
3. Its neighbor nodes are list = {B, E, F}
stored in list
Depth First Graph Traversal (Iterative)… Demo
While-loop executes

Since all the neighbors


are already visited,
Every neighbor of D that is nothing is pushed onto
not already visited, is pushed stack
to stack
Depth First Graph Traversal (Iterative)… Demo

Since stack is not empty,


While-loop executes

1. Stack is popped v=B


2. B is visited v is visited
3. Its neighbor nodes are list = {A, D}
stored in list
Depth First Graph Traversal (Iterative)… Demo
While-loop executes

Since all the neighbors


are already visited,
Every neighbor of D that is nothing is pushed onto
not already visited, is pushed stack
to stack
Depth First Graph Traversal (Iterative)… Demo

Stack is empty, While-loop


exits and so is dfs()
Breadth First Graph Traversal
proc bfs(G, v) // G is graph, v is a vertex
queue // An instance of Queue Data Structure
queue.eque(v)
while !queue.empty() do
vertex  queue.deque()
vertex.visitited  true
list  G.getAdjacencyList(vertex)
foreach node in list do
if node.visited = false then
queue.enque(node)
endif
next
next
BFS … Demo

bfs() is initially called as:


bfs(G, A)

Node A is added to Queue


BFS … Demo
Since Queue is not empty,
1. A is removed from Queue
2. Visited A
3. list = {B, C}
BFS … Demo
Every neighbor of A that is
not already visited, is added
to Queue
BFS … Demo
Since Queue is not empty,
1. B is removed from Queue
2. Visited B
3. list = {A, D}
BFS … Demo
Every neighbor of B that is
not already visited, is added
to Queue
BFS … Demo
Since Queue is not empty,
1. C is removed from Queue
2. Visited C
3. list = {A, E}
BFS … Demo
Every neighbor of C that is
not already visited, is added
to Queue
BFS … Demo
Since Queue is not empty,
1. D is removed from Queue
2. Visited D
3. list = {B, E, F}
BFS … Demo
Every neighbor of D that is
not already visited, is added
to Queue
BFS … Demo
Since Queue is not empty,
1. E is removed from Queue
2. Visited E
3. list = {C, D, F}
BFS … Demo
Every neighbor of E that is
not already visited, is added
to Queue
BFS … Demo
Since Queue is not empty,
1. E is removed from Queue
2. Visited E
3. list = {C, D, F}
BFS … Demo
Every neighbor of E that is
not already visited, is added
to Queue
BFS … Demo
Since Queue is not empty,
1. F is removed from Queue
2. Visited F
3. list = {D, E}
BFS … Demo
Since every neighbor of F is
already visited, nothing is
added to Queue
BFS … Demo
Since Queue is not empty,
1. F is removed from Queue
2. Visited F
3. list = {D, E}
BFS … Demo
Since every neighbor of F is
already visited, nothing is
added to Queue
BFS … Demo
Since Queue is not empty,
1. F is removed from Queue
2. Visited F
3. list = {D, E}
BFS … Demo
Since every neighbor of F is
already visited, nothing is
added to Queue
BFS … Demo
Since Queue is empty,
1. While loop exits, so is
bfs()
Applications of DFS
Finding Connected Components
Topological Sorting
Finding 2-Connected Components
Finding the Bridge of Graph
Finding Strongly Connected Components
Finding Bi-connectivity in Graphs
etc
Spanning Tree (ST)
“A spanning tree is a subset of Graph G, which has all the vertices covered
with minimum possible number of edges”
A spanning tree can contain no cycle
Graph G
A spanning tree cannot be disconnected
A graph can have multiple spanning trees

Spanning tree T1
Spanning tree T2
Spanning Tree (ST)
“A spanning tree is a subset of Graph G, which has all the
vertices covered with minimum possible number of edges”
Number of vertices for all spanning trees of a graph are Graph G
same
Number of edges for all spanning trees of a graph are same
All spanning trees form a minimally connected graph i.e.
one takes away one edge from ST and it is no more a
spanning tree
Adding one edge to ST will introduce a cycle i.e. ST is
maximally acyclic Spanning tree T1
Spanning Tree (ST) … Applications
Network Planning & Design
Network Routing Protocols
Cluster Analysis
Approximation Algorithms for NP-hard Problems
Image Registration & Segmentation Algorithms
Minimax Process Control
etc
Minimum Spanning Tree (MST)
“Minimum spanning tree is subset of edges of a
connected, weighted undirected graph that connects all
vertices together and bears the minimum possible total Spanning Tree T1
edge weight”
Minimum Spanning Tree is also called Minimum
Weight Spanning Tree
MST is a tree so it does not contain any cycle

Graph K Spanning Tree T2


Generic MST Algorithm
Minimum spanning tree is subset of edges of a connected, weighted undirected
graph that connects all vertices together and bears the minimum possible total
edge weight
Minimum Spanning Tree is also called Minimum Weight Spanning Tree
MST is a tree so it does not contain any cycle
Generic MST Algorithm
proc genericMST(G) // G = (V, X)
edges  sortAscendingOnWeight(G.X) // returns the array of edges
resultSet = {}
for j  1 to |edges| do
oneEdge  edges[j]
temp  resultSet U {oneEdge}
if !hasCycle(temp) then
resultSet  temp
end if
next
return resultSet Note: MST Algorithm only works
for connected graph.
end proc
Generic MST Algorithm
proc genericMST(G)
edges  sortAscendingOnWeight(G.X)
resultSet = {}
for j  1 to |edges| do
oneEdge  edges[j]
temp  resultSet U {oneEdge}
edges = {(D, F, 1), (C, F, 2), (A, D, 2), if !hasCycle(temp) then
(A, B, 3), (C, D, 3), (B, C, 4), (D, E, 4), resultSet  temp
(E, F, 5), (B, D, 6)}
resultSet = {} end if
next
return resultSet
end proc
Generic MST Algorithm
proc genericMST(G)
edges  sortAscendingOnWeight(G.X)
resultSet = {}
for j  1 to |edges| do
oneEdge  edges[j]
temp  resultSet U {oneEdge}
Edges = {(D, F, 1), (C, F, 2), (A, D, 2), (A, B, 3), (C, if !hasCycle(temp) then
D, 3), (B, C, 4), (D, E, 4), (E, F, 5), (B, D, 6)}
resultSet  temp
resultSet = {(D, F, 1), (C, F, 2) , (A, D, 2), (A, B, 3), end if
(D, E, 4)} next
return resultSet
end proc
Disjoint Set … Node
It is a data structure that supports a certain type of nodes. Every node contain three data members as
below:
Data member Description
1. data (type=int) Stores value of node
2. rank (type=int) Stores rank of node
3. parent Points to parent node
(type=node)
Disjoint Set … Operations
Disjoint Set supports only three operations:
Data member Description
1. makeSet Receives one node and returns a set containing that node only. Initializes the node
rank to zero and parent points to node itself. Also node becomes representative of
itself.
2. Union Joins two sets into one. Makes one node (containing max rank) as representative say
X. All nodes other than X have X as their parent. X is parent of itself. Rank of X is more
than all of its children.
3. findSet Returns representative node of set.
Kruskal’s Algorithm for MST proc kruskalMST(G) // G=(V,E) i.e. Set of vertices, Set of edges
resultSet  {}
vertices  G.V
foreach v in vertices do
makeSet(v)
next
edges sortAscendingByWeight(G.E) // Set of All Edges in G
foreach (u,v) ϵ edges do
if findSet(u) ≠ findSet(v) then
resultSet  resultSet ∪ {(u, v)}
union(u, v)
endif
return resultSet
End proc
Kruskal’s Algorithm for MST … Demonstration

resultSet={}
Vertices = {A, B, C, D, E, F}
{A}, {B}, {C}, {D}, {E}, {F}

Graph G
Kruskal’s Algorithm for MST … Demonstration
resultSet={}
Vertices = {A, B, C, D, E, F}
{A}, {B}, {C}, {D}, {E}, {F}
Edges = {(D,F), (A,D), (C,F), (A,B), (C,D),
(B,C), (D,E), (E,F), (B,D)}

Graph G
Kruskal’s Algorithm for MST … Demonstration
Edges = {(D,F), (A,D), (C,F), (A,B),
(C,D), (B,C), (D,E), (E,F), (B,D)}
(u,v) = (D, F)
If condition = TRUE
{A}, {B}, {C}, {D(rank=1), F(rank=0)},
{E}
resultSet={(D,F)}

Graph G
Kruskal’s Algorithm for MST … Demonstration
Edges = {(D,F), (A,D), (C,F), (A,B), (C,D),
(B,C), (D,E), (E,F), (B,D)}
(u,v) = (A, D)
If condition = TRUE
resultSet={(D, F), (A,D)}
{B}, {C}, {D, A, F}, {E}

Graph G
Kruskal’s Algorithm for MST … Demonstration
Edges = {(D,F), (A,D), (C,F), (A,B), (C,D),
(B,C), (D,E), (E,F), (B,D)}
(u,v) = (C,F)
If condition = TRUE
resultSet={(D,F), (A,D), (C,F)}
{B}, {D, A, F, C}, {E}

Graph G
Kruskal’s Algorithm for MST … Demonstration
Edges = {(D,F), (A,D), (C,F), (A,B),
(C,D), (B,C), (D,E), (E,F), (B,D)}
(u,v) = (A,B)
If condition = TRUE
resultSet={(D,F),(A,D),(C,F),
(A,B)}
{D, A, F, C, B}, {E}
Graph G
Kruskal’s Algorithm for MST … Demonstration
Edges = {(D,F), (A,D), (C,F), (A,B), (C,D),
(B,C), (D,E), (E,F), (B,D)}
{D,A,F,C,B}, {E}
resultSet={(D,F),(A,D),(C,F),(A,B)}
(u,v) = (C,D)
If condition = FALSE i.e No change in
resultSet
Graph G
Kruskal’s Algorithm for MST … Demonstration
Edges = {(D,F), (A,D), (C,F), (A,B), (C,D),
(B,C), (D,E), (E,F), (B,D)}
{D,A,F,C,B}, {E}
resultSet={(D,F),(A,D),(C,F),(A,B)}
(u,v) = (B, C)
If condition = FALSE i.e No change in
resultSet

Graph G
Kruskal’s Algorithm for MST … Demonstration
Edges = {(D,F), (A,D), (C,F), (A,B), (C,D),
(B,C), (D,E), (E,F), (B,D)}
(u,v) = (D,E)
If condition = TRUE
resultSet={(D,F),(A,D),(C,F),(A,B),(D,E)}
{D,A,F,C,B,E}

Graph G
Kruskal’s Algorithm for MST … Demonstration
Edges = {(D,F), (A,D), (C,F), (A,B), (C,D), (B,C),
(D,E), (E,F), (B,D)}
(u,v) = (E, F)
resultSet={(D,F),(A,D),(C,F),(A,B),(D,E)}
{D,A,F,C,B,E}
If condition = FALSE i.e. No change in resultSet

Graph G
Kruskal’s Algorithm for MST … Demonstration
Edges = {(D,F), (A,D), (C,F), (A,B), (C,D),
(B,C), (D,E), (E,F), (B,D)}
(u,v) = (B, D)
resultSet={(D,F),(A,D),(C,F),(A,B),(D,E)}
{D,A,F,C,B,E}
If condition = FALSE i.e. No change in
resultSet
Graph G
Kruskal’s Algorithm for MST … Demonstration
resultSet={(D,F),(A,D),(C,F),(A,B),(D,E)}

Graph G
Kruskal’s Algorithm for MST … Complexity
proc primMST(G, r) // G = (V, E)

Prim’s Algorithm for MST resultSet  {} //empty set


vertices  G.V
foreach v ϵ vertices do
v.key  ∞
v.parent  null
r.key  0
while vertices != {} do
u  findMinByKey(vertices)
vertices  vertices – u
if u.parent != null then
resultSet = resultSet U (u, u.parent)
endif
foreach v ϵ G.adjacentList(u) do
if v ϵ vertices AND (u,v).weight < v.key then
v.parent  u
v.key  (u,v).weight
end if
return resultSet
Prim’s Algorithm for MST

resultSet = {}
Prim’s Algorithm for MST

resultSet = {}
vertices = {A, B, C, D, E, F}
Prim’s Algorithm for MST

resultSet = {}
vertices = {A, B, C, D, E, F}
A(∞, null), B(∞, null), C(∞, null),
D(∞, null), E(∞, null), F(∞, null)
Prim’s Algorithm for MST
resultSet = {}
vertices = {A, B, C, D, E, F}
A(0, null), B(∞, null), C(∞, null),
D(∞, null), E(∞, null), F(∞, null)
Prim’s Algorithm for MST
resultSet = {}
A(0, null), B(∞, null), C(∞, null),
D(∞, null), E(∞, null), F(∞, null)
u=A
vertices = {B, C, D, E, F} // A is removed
If condition = false // A.parent is null
Prim’s Algorithm for MST
resultSet = {}
vertices = {B, C, D, E, F}
u=A
G.adjacentList = {B, D}
v=B
2nd if condition = true// B belongs to vertices
//AND (A, B).weight < B.key
A(0, null), B(3, A), C(∞, null),
D(∞, null), E(∞, null), F(∞, null)
Prim’s Algorithm for MST
resultSet = {}
vertices = {B, C, D, E, F}
u=A
G.adjacentList = {B, D}
v=D
2nd if condition = true // D belongs to vertices
// AND (A, D).weight < D.key
A(0, null), B(3, A), C(∞, null),
D(2, A), E(∞, null), F(∞, null)
Prim’s Algorithm for MST
While condition is TRUE // vertices is not EMPTY
u=D // key-wise smallest node
vertices = {B, C, E, F} // removed D from vertices
if condition is TRUE // D.parent is not null
//i.e. it is added to resultSet
resultSet = {(A,D)}
A(0, null), B(3, A), C(∞, null),
D(2, A), E(∞, null), F(∞, null)
Prim’s Algorithm for MST
resultSet = {(A,D)}
vertices = {B, C, E, F}
A(0, null), B(3, A), C(∞, null),
D(2, A), E(∞, null), F(∞, null)
u=D
1st If condition = true
u.adjacentList={A, B, C, E, F}
v=A
2nd if condition is false
Prim’s Algorithm for MST
resultSet = {(A,D)}
vertices = {B, C, E, F}
A(0, null), B(3, A), C(∞, null),
D(2, A), E(∞, null), F(∞, null)
u=D
1st If condition = true
u.adjacentList={A, B, C, E, F}
v=B
2nd if condition is false
Prim’s Algorithm for MST
resultSet = {(A,D)}
vertices = {B, C, E, F}
A(0, null), B(3, A), C(3, D),
D(2, A), E(∞, null), F(∞, null)
u=D
1st If condition = true
u.adjacentList={A, B, C, E, F}
v=C
2nd if condition is true
Prim’s Algorithm for MST
resultSet = {(A,D)}
vertices = {B, C, E, F}
A(0, null), B(3, A), C(3, D),
D(2, A), E(4, D), F(∞, null)
u=D
1st If condition = true
u.adjacentList={A, B, C, E, F}
v=E
2nd if condition is true
Prim’s Algorithm for MST
resultSet = {(A,D)}
vertices = {B, C, E, F}
A(0, null), B(3, A), C(3, D),
D(2, A), E(4, D), F(1, D)
u=D
1st If condition = true
u.adjacentList={A, B, C, E, F}
v=F
2nd if condition is true
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F)}
vertices = {B, C, E}
A(0, null), B(3, A), C(3, D),
D(2, A), E(4, D), F(1, D)
u=F
1st If condition = true
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F)}
vertices = {B, C, E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=F
1st If condition = true
v=C
2nd condition = true
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F)}
vertices = {B, C, E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=F
1st If condition = true
v=E
2nd condition = false
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F)}
vertices = {B, C, E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=F
1st If condition = true
v=D
2nd condition = false
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C)}
vertices = {B, E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=C
1st If condition = true
v=B
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C)}
vertices = {B, E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=C
1st If condition = true
v=B
2nd condition = false
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C)}
vertices = {B, E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=C
1st If condition = true
v=F
2nd condition = false
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C)}
vertices = {B, E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=C
1st If condition = true
v=D
2nd condition = false
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C), (A,B)}
vertices = {E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=B
1st If condition = true
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C), (A,B)}
vertices = {E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=B
1st If condition = true
v=A
2nd condition = false
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C), (A,B)}
vertices = {E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=B
1st If condition = true
v=D
2nd condition = false
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C), (A,B)}
vertices = {E}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=B
1st If condition = true
v=C
2nd condition = false
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C), (A,B), (D,E)}
vertices = {}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=E
1st If condition = true
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C), (A,B), (D,E)}
vertices = {}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=E
1st If condition = true
v =D
2nd if condition = false
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C), (A,B),
(D,E)}
vertices = {}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
u=E
1st If condition = true
v =F
2nd if condition = false
Prim’s Algorithm for MST
resultSet = {(A,D), (D,F), (F,C), (A,B), (D,E)}
vertices = {}
A(0, null), B(3, A), C(2, F),
D(2, A), E(4, D), F(1, D)
1st If condition = FALSE
Prim’s Algorithm for MST

resultSet = {(A,D), (D,F), (F,C), (A,B), (D,E)}


Single Source – All Destination Shortest Distance Problem
We are given a weighted graph and a vertex (source). Single Source-All Destination
Shortest Distance Problem aims to determine shortest distance of all vertices in
graph starting from the source.
Weights on edges are also referred as costs. Edges may be directed as well as
undirected.
Dijkstra’s Algorithm
 Solves single source shortest distance problem on weighted directed/undirected graph
 Edge weights should be non-negative
 Graph must be connected
Bellman Ford Algorithm
 Single Source All Destination
 Allows negative weight edges
 Detects negative cycles
proc dijkstra(G, s)
dist[s]  0 Dijkstra’s … The Algorithm
Q  G.V
foreach v in Q – s do
dist[v]  ∞
visitedVertices  {}
while Q != {} do
u  extractMin(Q)
Q  Q – {u}
visitedVertices  visitedVertices U {u}
foreach v in G.adjacencyList(u) do
if dist[v] > dist[u]+edge(u,v) then
dist[v]  dist[u]+edge(u,v)
endif
next
next
Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration

Next iteration of while


Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration

Next iteration of while


Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration

Next iteration of while


Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration

Next iteration of while


Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration
Dijkstra’s … The Algorithm … Demonstration

Next iteration of while


Dijkstra’s … The Algorithm … Demonstration
Bellman Ford Algorithm
Single Source Shortest Path Algorithm
Finds shortest path of all vertices starting from one given vertex
Algorithm cannot detect shortest path in case of negative cycle
Bellman Ford … The Algorithm
proc bellmanford(G, s)
initialize(G, s) Initialize(G, s) function initializes
the distance value of all nodes
vertices  G.V from the source node equal to ∞
for i1 to |vertices|-1 do and the distance of source from
itself to 0.
foreach edge (v, w) in G.E do
if dist[w] > dist[v]+weight(v, w) then
dist[w]  dist[v]+weight(v, w)
parent(w)  v
foreach edge(v, w) in G.E do
if dist[w] > dist[v] + edge(v, w) then
return “negative cycle”
Bellman Ford Algorithm … Demonstration

Execute it yourself
Bellman Ford Algorithm … Demonstration

s=A
vertices = {A, B, C, D, E, F}
All nodes initialized i.e. distance from source to
source is 0 and distance from source to every other
node is ∞
Bellman Ford Algorithm … Demonstration

For-loop execution … i=1 … 5


Foreach loop will process every edge
Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2), (D, E, 7), (D, F, 1), (E, F,
-1), (F, A, 5), (F, C, 2)}
dist[A]=0, dist[B]=∞, dist[C]=∞, dist[D]=∞, dist[E]=∞, dist[F]=∞
Bellman Ford Algorithm … Demonstration
Processing edge = (A, B, 4)
If dist[B] > dist[A] + weight(AB)
∞>0+4 … condition is true
dist[B] is updated to 0+4 and parent of B is assigned A

Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2),
(D, E, 7), (D, F, 1), (E, F, -1), (F, A, 5), (F, C, 2)}
Bellman Ford Algorithm … Demonstration
Processing edge = (A, D, 6)
If dist[D] > dist[A] + weight(AD)
∞>0+6 … condition is true
dist[D] is updated to 0+6 and parent of D is assigned A

Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2),
(D, E, 7), (D, F, 1), (E, F, -1), (F, A, 5), (F, C, 2)}
Bellman Ford Algorithm … Demonstration
Processing edge = (B, C, 5)
If dist[C] > dist[B] + weight(BC)
∞>4+5 … condition is true
dist[C] is updated to 4+5 and parent of C is assigned B

Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2),
(D, E, 7), (D, F, 1), (E, F, -1), (F, A, 5), (F, C, 2)}
Bellman Ford Algorithm … Demonstration
Processing edge = (B, D, 3)
If dist[D] > dist[B] + weight(BD)
6>4+3 … condition is FALSE
No change in data

Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2),
(D, E, 7), (D, F, 1), (E, F, -1), (F, A, 5), (F, C, 2)}
Bellman Ford Algorithm … Demonstration
Processing edge = (C, E, 2)
If dist[E] > dist[C] + weight(CE)
∞>9+2 … condition is TRUE
dist[E] is assigned 9+2 and parent of E is assigned C

Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2),
(D, E, 7), (D, F, 1), (E, F, -1), (F, A, 5), (F, C, 2)}
Bellman Ford Algorithm … Demonstration
Processing edge = (D, E, 7)
If dist[E] > dist[D] + weight(DE)
11 > 6 + 7 … condition is FALSE
No change in data

Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2),
(D, E, 7), (D, F, 1), (E, F, -1), (F, A, 5), (F, C, 2)}
Bellman Ford Algorithm … Demonstration
Processing edge = (D, F, 1)
If dist[F] > dist[D] + weight(DF)
∞>6+1 … condition is TRUE
dist[F] is assigned 6+1 and parent of F is assigned D

Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2),
(D, E, 7), (D, F, 1), (E, F, -1), (F, A, 5), (F, C, 2)}
Bellman Ford Algorithm … Demonstration
Processing edge = (E, F, -1)
If dist[F] > dist[E] + weight(EF)
7 > 11 + (-1) … condition is FALSE
No change in data

Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2),
(D, E, 7), (D, F, 1), (E, F, -1), (F, A, 5), (F, C, 2)}
Bellman Ford Algorithm … Demonstration
Processing edge = (F, A, 5)
If dist[A] > dist[F] + weight(FA)
0>7+5 … condition is FALSE
No change in data

Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2),
(D, E, 7), (D, F, 1), (E, F, -1), (F, A, 5), (F, C, 2)}
Bellman Ford Algorithm … Demonstration
Processing edge = (F, C, 2)
If dist[C] > dist[F] + weight(FC)
9>7+2 … condition is FALSE
No change in data

Edges = {(A, B, 4), (A, D, 6), (B, C, 5), (B, D, 3), (C, E, 2),
(D, E, 7), (D, F, 1), (E, F, -1), (F, A, 5), (F, C, 2)}
Bellman Ford Algorithm … Demonstration

Note: External loop has been iterated only once, one


needs to iterates it |vertices|-1 to ensure that all
possibilities of finding shortest distance / path have been
covered.
A* Shortest Path Graph Algorithm
Often used for path finding and graph traversal in real life problems and games
While looking for the shortest path between the source and destination nodes, a*
algorithm uses some guidance (called heuristics)
On every step of iterative search process (as said above), heuristics function
guides the process which nodes will be chosen next
Heuristic function typically estimates the smallest cost (distance) from source
node to the destination node
Estimated heuristic function takes very little time to execute and does not add
much cost during execution of a* algorithm
A* Algorithm … Heuristics Function
While calculating the cost of path from source to an destination node, A*
algorithm uses the following formula on every step:
f(n) = g(n) + h(n) where g(n) is the actual cost for reaching to node n starting from
source node and h(n) is the estimated cost (typically the cost of cheapest path from
node n to destination node)
A heuristic function h(n) is only admissible if for every node n,
h(n) ≤ g(n), where g(n) is the true cost to reach the goal state from n.
An admissible heuristic never overestimates the cost to reach the goal, i.e., it is
optimistic
A* Algorithm … Heuristics Function

• f(n) = g(n) + h(n)


• g(n) = “cost from the starting node to reach n”
• h(n) = “estimate of the cost of the cheapest path from n to the
goal node”
h(n)
20
g(n)
15 n
10 5
15
18
20
25

33
A* … The Algorithm
Properties of A*
A* generates an optimal solution if h(n) is an admissible heuristic and the
search space is a tree:
h(n) is admissible if it never overestimates the cost to reach the destination
node
A* generates an optimal solution if h(n) is a consistent heuristic and the
search space is a graph:
h(n) is consistent if for every node n and for every successor node n’ of n:
h(n) ≤ c(n,n’) + h(n’)

h(n)
n
d
c(n,n’) h(n’)
n’
• If h(n) is consistent then h(n) is admissible
•Frequently when h(n) is admissible, it is also consistent
Admissible Heuristics
A heuristic is admissible if it is too optimistic, estimating the cost to be
smaller than it actually is.

Example:
In the road map domain,

h(n) = “Euclidean distance to destination”

is admissible as normally cities are not connected by roads that make straight
lines

You might also like