Algorithms Unit 2
Algorithms Unit 2
Edge
An edge is a connecting link between two vertices. Edge is also known as Arc. An edge is
represented as (startingVertex, endingVertex). Vertices A and B is represented as (A,B). In above
example graph, there are 7 edges (i.e., (A,B), (A,C), (A,D), (B,D), (B,E), (C,D), (D,E)).
Directed Edge
A directed egde is a unidirectional edge. If there is directed edge between vertices A and
B then edge (A , B) is not equal to edge (B , A).
Unit II 1
Weighted Edge
A weighted edge is a edge with value (cost) on it. Weighted graphs can be further
classified as directed weighted graphs and undirected weighted graphs.
Connected Graph
A graph is connected if any two vertices of the graph are connected by a path.
Vertex 1 Vertex 2 PATH
a b ab
a c a b c, a c
a d a b c d, a c d
b c bac,bc
c d cd
Disconnected Graph
A graph is disconnected if at least two vertices of the graph are not connected by a path.
Degree of a vertex
Total number of edges connected to a vertex is said to be degree of that vertex. The degree
of a vertex is indicated with the help of 𝑑𝑒𝑔(𝑣). If there is a simple graph, which contains n number of
vertices, in this case, the degree of any vertex will be:
𝐷𝑒𝑔(𝑣) = 𝑛 − 1 ∀ 𝑣 ∈ 𝐺
Indegree - deg+(v)
Total number of incoming edges connected to a vertex is called as indegree of that
vertex.
Unit II 2
Outdegree – deg-(v)
Total number of outgoing edges connected to a vertex is called as outdegree of that
vertex.
Example 1:
Example 2:
Vertex In Out
0 1 2
1 2 1
2 2 3
3 2 2
4 2 2
5 2 2
6 2 1
Origin
If an edge is directed, its first endpoint is said to be the origin of it.
Destination
If an edge is directed, its first endpoint is said to be the origin of it and the other endpoint
is said to be the destination of that edge.
Adjacent
If there is an edge between vertices A and B then both A and B are said to be adjacent. In other
words, vertices A and B are said to be adjacent if there is an edge between them.
Parallel edge
If two vertices are connected through more than one edges then we can say there exist parallel
edges in between both vertices.
Unit II 3
Self-loop
If the start point and endpoint of an edge is the same vertex then there exists a self-loop.
Simple graph
Graph with no parallel edge and self-loop is called simple graph
Complete graph/Clique
A complete graph or clique is a simple graph in which every pair of vertices has an edge.n
vertices complete graph is denoted by Kn.
Unit II 4
2.1.2 Visualize graphs generated in NetworkX using Matplotlib
NetworkX is a Python library for studying graphs and networks..
Step 1: Import networkx and matplotlib.pyplot in the project file.
Step 2: Generate a graph using networkx.
Step 3: Now use draw() function of networkx.drawing to draw the graph.
Step 4: Use savefig(“filename.png”) function of matplotlib.pyplot to save the drawing of
graph in filename.png file.
Simple Python program to draw a Graph Output
# importing networkx
import networkx as nx
# importing matplotlib.pyplot
import matplotlib.pyplot as plt
g = nx.Graph()
g.add_edge(1, 2)
g.add_edge(2, 3)
g.add_edge(3, 4)
g.add_edge(1, 4)
g.add_edge(1, 5)
nx.draw(g)
Output
nx.draw(G, with_labels = True,
font_color = 'white',
node_shape='s')
Output
g = nx.cycle_graph(5) Nodes in graph : [0, 1, 2, 3, 4]
Edges in the graph : [(0, 1), (0, 4), (1,
print("Nodes in graph : ", g.nodes()) 2), (2, 3), (3, 4)]
print("Edges in the graph : ", g.edges())
g = nx.Graph() Output
g.add_edges_from([(1,2),(2, 3),
(3,4),(1,4),(1,5),
(5,6), (5,7),
(4,8),(3,8)])
Unit II 5
# drawing in circular layout
df = pd.DataFrame({
'from':['A', 'B', 'C','A'],
'to':['D', 'A', 'E','C']})
# Plot it
nx.draw(G, with_labels=True)
plt.show()
Unit II 6
2.1.3 Real-Time Applications of Graph:
• Graphs are used to represent flow of control in computers.
• Graphs are used in social networking sites where users act as nodes and connection
between them acts as edges.
• In an operating system, graphs are used as resource allocation graphs.
• Graphs are used in Google maps to find the shortest route.
• Graphs are also used in airlines system for effective route optimization.
• In-state transition diagrams, the graph are used to represent their states and their
transition.
• In transportation, graphs are used to find the shortest path.
• In circuits, graphs can be used to represent circuit points as nodes and wires as edges.
• Graphs are used in solving puzzles with only one solution, such as mazes.
• Graphs are used in computer networks for Peer to peer (P2P) applications.
• Graphs basically in the form of DAG(Directed acyclic graph) are used as alternative to block
chain for crypto-currency.
• By using graphs we can easily find the shortest path, neighbors of the nodes, and many more.
• Graphs are used to implement algorithms like DFS and BFS.
• It is used to find minimum spanning tree which has many practical applications.
• It helps in organizing data.
• Because of its non-linear structure, helps in understanding complex problems and their
visualization.
Demerits
• Graphs use lots of pointers which can be complex to handle.
• It can have large memory complexity.
• If the graph is represented with an adjacency matrix then it does not allow parallel edges
and multiplication of the graph is also difficult.
Unit II 7
Undirected graph representation
In the above examples, 1 represents an edge from row vertex to column vertex, and 0
represents no edge from row vertex to column vertex.
Merits
• Representation is easier to implement.
• Adding or deleting an edge takes constant time.
Demerits
• The size of adjacency matrix is V2. Suppose there is a graph with 1000 vertices and 1 edge.
The array of size 10002is used for storing one edge which is a waste of memory.
• It takes a lot of space and time to visit all the neighbours of a vertex, we have to traverse all the
vertices in the graph, which takes much time.
Unit II 8
2.2.2. Incidence Matrix
In this representation, the graph is represented using a matrix of total number of
vertices by total number of edges. A graph with 4 vertices and 6 edges is represented using a matrix
of size 4X6. In this matrix, rows represent vertices and columns represent edges. The matrix is filled
with 0, 1 or -1.
• 0→ represents that the row edge is not connected to column vertex
• 1 →represents that the row edge is connected as the outgoing edge to column vertex
• -1→ represents that the row edge is connected as the incoming edge to column vertex.
Example 1:
Example 2:
Example 3:
Unit II 9
Branches
e f
Example 4:
Nodes Branches
e1 e2 e3 e4 e5 e6
v1 1 1 0 0 0 0
v2 0 0 1 1 0 1
v3 0 0 0 0 1 1
v4 1 0 1 0 0 0
v5 0 1 0 1 1 0
Unit II
10
Merits
• Easy to find successors of a node
• Easy to find all neighbouring nodes
• Space efficient as it only stores connected nodes
Demerits
• It is time consuming to check if an edge is part of a graph
Unit II
11
OPERATIONS ADJACENCY MATRIX ADJACENCY LIST
Time Complexity
Representation Space
of Graph Complexity Add Remove Remove
Add Edge Query
Vertex Vertex Edge
Adjacency Matrix O(|V|2) O(|V|2) O(|1) O(|V|2) O(|1) O(|1)
Incidence Matrix O(|V| + |E|) O(|V| + |E|) O(|V| + |E|) O(|V| + |E|) O(|V| + |E|) O(|E|)
Adjacency List O(|V| + |E|) O(|1) O(|1) O(|V| + |E|) O(|E|) O(|V|)
Unit II
12
2.2.6 Visualize representations of Graphs generated in NetworkX using Matplotlib
G = nx.Graph(adjacency_matrix,nodetype=int)
Undirected Graph
First we create an undirected graph. When displaying the edges, we see that all edges are present
independent of if they were defined in both rows or just in one.
G = nx.Graph(adjacency_matrix, Output
nodetype=int)
G.edges() EdgeView([(0, 1), (0, 2), (0,
3), (1, 3)])
Directed Graph
In contrast when we use the same adjacency matrix to create a directed graph, only the edge from node 3 to node
0 is added, no edge is added in the opposite direction from node 0 to 3
G = nx.DiGraph(adjacency_matrix, OutEdgeView([(0, 1), (0, 2),
nodetype=int) (1, 0), (1, 3), (2, 0), (3,
G.edges() 0), (3, 1)])
# Printing Adjacency List Output
g = nx.Graph() 1 245
g.add_edges_from([(1,2), 2 3
(2, 3), 3 48
(3,4), 4 8
(1,4), 5 67
(1,5), 6
(5,6), 7
(5,7), 8
(4,8),
(3,8)])
Unit II
13
# drawing a graph
nx.draw(g, with_labels = True)
print()
nx.draw(G, with_labels = True)
print("Adjacency List for node 3")
Unit II
14
print(G.adj[3])
print("Degree for node 3")
print(G.degree[3])
Output:
Out edges of node 4 are: [(4, 5), (4, 6)]
In Degree of node 2 is: 2
Successors of node 4 are: [5, 6]
Predecessors of node 2 are: [1, 5]
Unit II
15
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph()
# Using add_edge
G.add_edge(1, 2, weight = 12.5)
G.add_edge(3, 2, weight = 50.0)
G.add_edge(1, 3, weight = 17)
G.add_edge(4, 2, weight = 100)
G.add_edge(2, 5, weight = 1)
G.add_edge(4, 6, weight = 25.5)
G.add_edge(7, 4, weight = 175)
G.add_edge(5, 8, weight = 90)
Pos = nx.circular_layout(G)
nx.draw(G, pos, with_labels = True, font_weight = 'bold')
edge_weight = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G, pos, edge_labels = edge_weight)
plt.show()
Output:
Unit II
16
2.3.1 Depth-first search
DFS is an algorithm for traversing a finite graph. Depth First Traversal (or Search) for a graph
is similar to Depth First Traversal of a tree. The only difference is, graphs may contain cycles (a node
may be visited twice). DFS visits the child vertices before visiting the sibling vertices; that is, it
traverses the depth of any particular path before exploring its breadth. A stack (often the
program's call stack via recursion) is generally used when implementing the algorithm.
DFS traversal of a graph produces a spanning tree as final result. Spanning Tree is a graph without
loops. We use Stack data structure with maximum size of total number of vertices in the graph to
implement DFS traversal.A standard DFS implementation puts each vertex of the graph into one of two
categories:
• Visited
• Not Visited
The purpose of the algorithm is to mark each vertex as visited while avoiding cycles.
Unit II
17
We start from vertex 0, the DFS algorithm starts by putting it in the Visited list and putting all its adjacent
vertices in the stack.
Next, we visit the element at the top of stack i.e. 1 and go to its adjacent nodes. Since 0 has already
been visited, we visit 2 instead.
Vertex 2 has an unvisited adjacent vertex in 4, so we add that to the top of the stack and visit it.
After we visit the last element 3, it doesn't have any unvisited adjacent nodes, so we have
completed the Depth First Traversal of the graph.
Unit II
18
2.3.1.2 Example 2 - Directed Graph:
# Driver Code
print("Following is the Depth-First Search")
dfs(visited, g, '5')
Unit II
19
Explanation for DFS algorithm:
It first checks if the current node is unvisited - if yes, it is appended in the visited set. Then
for each neighbour of the current node, the DFS function is invoked again.
The base case is invoked when all the nodes are visited. The function then returns.
BFS traversal of a graph produces a spanning tree as final result. For simplicity, it is assumed that all
vertices are reachable from the starting vertex. A standard BFS implementation puts each vertex of
the graph into one of two categories:
• Visited
• Not Visited
The purpose of the algorithm is to mark each vertex as visited while avoiding cycles.
Unit II
20
We start from vertex 0, the BFS algorithm starts by putting it in the Visited list and putting all its adjacent
vertices in the stack.
Next, we visit the element at the front of queue i.e. 1 and go to its adjacent nodes. Since 0 has already
been visited, we visit 2 instead.
Vertex 2 has an unvisited adjacent vertex in 4, so we add that to the back of the queue and visit 3, which
is at the front of the queue.
Only 4 remains in the queue since the only adjacent node of 3 i.e. 0 is already visited. We visit it.
Unit II
21
Since the queue is empty, we have completed the Breadth First Traversal of the graph.
Unit II
22
visited.append(node)
queue.append(node)
# Driver Code
print("Following is the Breadth-First Search")
bfs(visited, graph, '5') # function calling
2.4 Connectivity
A graph is said to be connected if there is a path between every pair of vertex. From every
vertex to any other vertex, there should be some path to traverse. That is called the
connectivity of a graph. A graph with multiple disconnected vertices and edges is said to be
disconnected.
Example 1
In the following graph, it is possible to travel from one vertex to any other vertex. For
example, one can traverse from vertex ‘a’ to vertex ‘e’ using the path ‘a-b-e’.
Example 2
In the following example, traversing from vertex ‘a’ to vertex ‘f’ is not possible because there is
no path between them directly or indirectly. Hence it is a disconnected graph.
Unit II
24
2.4.2 Cut Edge (Bridge)
Let ‘G’ be a connected graph. An edge ‘e’ ∈ G is called a cut edge if ‘G-e’ results in a
disconnected graph. If removing an edge in a graph results in to two or more graphs, then
that edge is called a Cut Edge.
Example
In the following graph, the cut edge is [(c, e)].
By removing the edge (c, e) from the graph, it becomes a disconnected graph.
In the above graph, removing the edge (c, e) breaks the graph into two which is nothing but a
disconnected graph. Hence, the edge (c, e) is a cut edge of the graph.
Unit II
25
To disconnect the above graph G, we have to remove the three edges. i.e. bd, be and ce. We
cannot disconnect it by removing just two of three edges. Hence, {bd, be, ce} is a cut set. After
removing the cut set from the above graph, it would look like as follows:
From the above graph, by removing two minimum edges, the connected graph becomes
disconnected graph. Hence, its edge connectivity is 2. Therefore the above graph is a 2- edge-
connected graph.
Here are the following four ways to disconnect the graph by removing two edges
Examples of Connectivity
Example 1
Calculate λ(G) and K(G) for the following graph −
Solution
From the graph,
• δ(G) = 3
• K(G) ≤ λ(G) ≤ δ(G) = 3 (1)
• K(G) ≥ 2 (2)
Deleting the edges {d, e} and {b, h}, we can disconnect G. Therefore,
• λ(G) = 2
• 2 ≤ λ(G) ≤ δ(G) = 2 (3)
• From (2) and (3), vertex connectivity K(G) = 2
Example 2
If a complete graph has a total of 20 vertices, then find the number of edges it may
contain.
Solution
The formula for the total number of edges in a k graph is given by;
Unit II
27
Number of edges = 𝑛(𝑛 − 1)/2
= 20(20 − 1)/2
=10(19)
=190
Hence, it contains 190 edges.
Example 3
If a graph has 40 edges, then how many vertices does it have?
Solution
Number of edges = 𝑛 (𝑛 − 1)/2
40 = 𝑛(𝑛 − 1)/2
=> n(n-1) = 80
n2 – n – 80 = 0
On solving the above quadratic equation, we get; n ≈ 9.45, -8.45 Since,
the number of vertices cannot be negative.
Therefore, number of vertices ≈ 9
Example 4
Calculate the degrees for the following graphs.
Graph G Graph H
Solution
In Graph G, deg(a)=2, deg(b)=deg(c)=deg(f)=4, deg(d)=1, deg(e)=3, and deg(g)=0.There are two
vertices d and e with odd number of degrees.
In Graph H, deg(a)=4, deg(b)=deg(e)=6, deg(c)=1, and deg(d)=5.There are two vertices c and d
with odd number of degrees.
Example 5
Calculate the in-degrees and out-degrees for the following graph.
Solution
The in-degree in G are deg−(a)=2, deg−(b)=2, deg−(c)=3, deg−(d)=2, deg−(e)=3, deg−(f)=0
Unit II
28
The out-degree in G are deg+(a)=4, deg+(b)=1, deg+(c)=2, deg+(d)=2, deg+(e)=3, deg+(f)=0
Example 6
How many edges does a complete graph have?
Solution
A complete graph on n vertices has = 𝑛 (𝑛 − 1)/2 edges
Example 7
Calculate edge connectivity for the following graph.
Solution
For graph G1, {{c, e}} is an edge cut. Hence, (G1)=1.
For graph G2, {{a, b}, {b, c}} and {{a, c}, {b, c}} are edge cuts. Hence, (G2)=2.
For graph G3, {{a, b},{a, g}} and {{b, c},{f, g}} are edge cuts. Hence, (G3)=2
For graph G4, {{b, c}, {a, f}, {f, g}} is an edge cut. Hence, (G4)=3
For graph G5, {{a, b}, {a, g}, {a, h}} is an edge cut. Hence, (G5)=3
Graph G1
Graph G2
Unit II
29
Graph G3
Graph G4
Graph G5
Example 8
Calculate vertex connectivity for the following graph.
Solution
For graph G1, either {c} or {e} is a vertex cut. Hence, K(G1) = 1 For graph
G2, {c} is a vertex cut. Hence, K(G2) = 1
For graph G3, either{b, g} or {c, f} is a vertex cut. Hence, K(G3) = 2 For graph
G4, {c, f} is a vertex cut. Hence, K(G4) = 2
For graph G5, {b, c, f} is a vertex cut. Hence, K(G5) = 3
Unit II
30
Graph G2
Graph G3
Graph G4
Graph G5
Unit II
31
Following are some examples:
Biconnected Graphs
A connected graph is Biconnected if it is connected and doesn’t have any Articulation Point.
We mainly need to check two things in a graph.
• The graph is connected.
• There is not articulation point in graph.
We start from any vertex and do DFS traversal. In DFS traversal, we check if there is any
articulation point. If we don’t find any articulation point, then the graph is Biconnected.
Finally, we need to check whether all vertices were reachable in DFS or not. If all vertices
were not reachable, then the graph is not even connected.
If each strongly connected component is treated as a single node, the graph becomes a
directed acyclic graph. Just like nodes in a directed graph, a strongly connected
Unit II
32
components with no incoming edges is known as a source and one without any outgoing edges
is known as a sink.
Finding the strongly connected components of a directed graph is the most complex of the
algorithms shown here. This algorithm (often referred to as the Kosaraju
or Kosaraju-Sharir algorithm) performs DFS twice.
A graph can be represented as 𝐺(𝑉, 𝐸), where V is the number of vertices, and E is the number of edges.
Thespanning tree is a subset to a connected graph G would be represented as G`(V`, E`).
• V` = V means that the number of vertices in the spanning tree would be the same as the number
of vertices in the graph.
• E` = |V| - 1 means that number of edges in the spanning tree is the subset of the number of edges
in the original graph ie. E` € E
Unit II
33
Figure . Minimum spanning Tree (MST)
We found three spanning trees for one complete graph. A complete undirected graph can have
maximum nn-2 number of spanning trees, where n is the number of vertices.
• When n = 3,number of spanning trees is 33−2 = 3.
• When n = 4,number of spanning trees is 44−2 = 16.
Unit II
34
2.5.4.1 Kruskal’sMinimum Spanning Tree Algorithm
Kruskal's Algorithm is used to find the minimum spanning tree for a connected weighted graph.
The main target of the algorithm is to find the subset of edges by using which we can traverse every
vertex of the graph. It follows the greedy approach to find an optimum solution at every stage instead
of focusing on a global optimum.
Steps
Step 1: First, sort all the edges from low weight to high.
Step 2: Now, take the edge with the lowest weight and add it to the spanning tree. If the edge to be
added creates a cycle, then reject the edge.
Step 3: Continue to add the edges until we reach all vertices, and a minimum spanning tree is
created.
2.5.4.1.2 Example
Given Graph G(V,E):
.
Step 1: Step 2:
Removing parallel edges or loops from the Include edges in the Minimum spanning
graph. Tree(MST) such that the included edge would not
form a cycle in the tree structure. Pick the edge
EF, as it has a minimum weight is 2.
Step 3: Step 4:
Add edge FD to the spanning tree. Add edge BC and edge CF to the spanning tree as it
does not generate any loop.
Unit II
35
Step 5: Step 6:
Next add edge CD. This edge generates the loop in the Now add edge BF. This edge also creates the loop;
tree structure. So, discard this edge. hence discard it.
Step 7: Step 8:
Next add edge BD. This edge also formulates a loop, Next add edge AB. By including this node, the
so discard it. MST includes all 5 edges, so we don’t need to
traverse further. The final MST is below:
Unit II
36
# Add nodes
nodes_list = [1, 2, 3, 4, 5, 6, 7]
G.add_nodes_from(nodes_list)
plt.figure()
pos = nx.spring_layout(G)
weight_labels = nx.get_edge_attributes(G,'weight')
nx.draw(G,pos,font_color = 'white', node_shape = 's', with_labels = True,)
nx.draw_networkx_edge_labels(G,pos,edge_labels=weight_labels)
print(sorted(mst.edges(data=True)))
Output:
[(1, 4, {'weight': 4}), (2, 3, {'weight': 2}), (2, 5, {'weight': 4}), (4,
5, {'weight': 3}), (4, 7, {'weight': 4}), (6, 7, {'weight': 3})]
Unit II
37
Steps
Step 1: Determine the arbitrary starting vertex.
Step 2: Keep repeating steps 3 and 4 until the fringe vertices (vertices not included in MST)
remain.
Step 3: Select an edge connecting the tree vertex and fringe vertex having the minimum weight.
Step 4: Add the chosen edge to MST if it doesn’t form any closed cycle.
Step 5: Exit
2.5.4.2.2 Example
Given weighted graph is
Step 1 Step 2
First, we have to choose a vertex from the above Add the shortest edge from vertex B. There are two
graph. Let's choose B. edges from vertex B ie. BC with weight 10 and edge
BD with weight 4. Among the edges, the edge BD has
the minimum weight. So, add it to the MST.
Step 3 Step 4
Again, choose the edge with the minimum Now, select the edge CD, and add it to the MST.
weight. In this case, the edges DE and DC are such
edges. DC has weight 2 and DE have weight 1.
So, select edge DE
Unit II
38
Step 5 Cost:
Now, choose the edge CA. Here, we cannot select the Cost of MST = 4 + 2 + 1 + 3 = 10 units.
edge CE as it would create a cycle to the graph.
So, choose the edge CA and add it to the MST.
selected_node = [0, 0, 0, 0, 0]
weight = 0
no_edge = 0
selected_node[0] = True
minimum = INF
a = 0
b = 0
Unit II
39
for m in range(N):
if selected_node[m]:
for n in range(N):
if ((not selected_node[n]) and G[m][n]):
# not in selected and there is an edge
if minimum > G[m][n]:
minimum = G[m][n]
a = m
b = n
print(str(a) + " --> " + str(b) + " : " + str(G[a][b]))
weight = weight + G[a][b]
selected_node[b] = True
no_edge += 1
Output:
Edge : Weight
0 --> 1 : 2
1 --> 2 : 3
2 --> 3 : 1
3 --> 4 : 4
Total Weight : 10
#Program 2
import matplotlib.pyplot as plt
import networkx as nx
import pylab
# Add nodes
nodes_list = [1, 2, 3, 4, 5, 6, 7]
G.add_nodes_from(nodes_list)
pos=nx.spring_layout(G)
pylab.figure(1)
nx.draw(G,pos, with_labels= 'true')
# use default edge labels
nx.draw_networkx_edge_labels(G,pos)
Unit II
40
# Calculate a minimum spanning tree of an undirected weighted graph with
# the Prim algorithm
mst = nx.minimum_spanning_tree(G, algorithm='prim')
print(sorted(mst.edges(data=True)))
Output:
[(1, 2, {'weight': 1}), (1, 4, {'weight': 4}), (2, 3, {'weight': 2}), (4, 5,
{'weight': 3}), (4, 7, {'weight': 4}), (6, 7, {'weight': 3})]
Unit II
41
Note 2:
If all the edge weights are not distinct, then both the algorithms may not always produce
the same MST.However, cost of both the MSTs would always be same in both the cases.
Unit II
42
2.6 Shortest path Algorithms
Shortest path algorithms are a family of algorithms used for solving the shortest path problem.
Unit II
43
2.6.2 Single Source Shortest Paths
Given a connected weighted directed graph 𝐺(𝑉, 𝐸), associated with each edge (𝑢, 𝑣⟩ ∈
𝐸, there is a weight w(u,v). The single source shortest paths (SSSP) problem is to find a shortest path
from a given source r to every other vertex 𝑣 ∈ 𝑉 − {𝑟}.The weight (length) of a path
𝑝 = (𝑉0, 𝑉1, … , 𝑉𝑘⟩ is the sum of the weights of its constituent edges:
𝑘
𝑊(𝑃𝑎𝑡ℎ 𝑃) = ∑ 𝑊(𝑉𝑖−1 , 𝑉𝑖)
𝑖=1
2.6.2.1.2 Pseudocode
Dijkstra’s algorithm in its original form, takes as input a graph with non-negative
weights, a source node (starting point), and a target node (final destination), and returns the
shortest path and the cost of that path. The algorithm uses two labels for each node to define the cost
from the source node to the specific node and the previous node respectively. The pseudocode of
the algorithm is the following:
Unit II
44
14 selected_node is characterized as visited
15
16 for each neighbor v of selected_node not visited:
17 alt ← selected_node distance from source node +
18 length(selected_node, v)
19 if alt <neighbor distance from source node:
20 neighbor distance from source node ← alt
21 neighbor previous node ← selected_node
22 calculate the path
23 return path, target node distance from start
First, we have to consider any vertex as a source vertex. Suppose we consider vertex 0 as a
source vertex.Here we assume that 0 as a source vertex, and distance to all the other
vertices is infinity. Initially, we do not know the distances. First, we will find out the vertices
which are directly connected to the vertex 0. From the above graph we can observe that two
vertices are directly connected to vertex 0.
Let's assume that the vertex 0 is represented by 'x' and the vertex 1 is represented by 'y'. The
distance between the vertices can be calculated by using the below algorithm:
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (0 + 4) <∞
= 4 <∞
Since 4 < ∞ so we will update d(y) from ∞ to 4.
Unit II
45
Now we consider vertex 0 same as 'x' and vertex 4 as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (0 + 8) <∞
= 8 <∞
Therefore, the value of d(y) is 8. We replace the infinity value of vertices 1 and 4 with the values 4 and 8
respectively. Now, we have found the shortest path from the vertex 0 to 1 and 0 to 4. Therefore,
vertex 0 is selected. Now, we will compare all the vertices except the vertex 0. Since vertex 1 has the
lowest value, i.e., 4; therefore, vertex 1 is selected.
Since vertex 1 is selected, so we consider the path from 1 to 2, and 1 to 4. We will not consider the path
from 1 to 0 as the vertex 0 is already selected.
First, we calculate the distance between the vertex 1 and 2. Consider the vertex 1 as 'x', and the vertex 2
as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (4 + 8) < ∞
= 12 < ∞
Now, we calculate the distance between the vertex 1 and vertex 4. Consider the vertex 1 as 'x' and the
vertex 4 as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (4 + 11) < 8
= 15 < 8
Since 15 is not less than 8, we will not update the value d(4) from 8 to 12.
Till now, two nodes have been selected, i.e., 0 and 1. Now we have to compare the nodes except
the node 0 and 1. The node 4 has the minimum distance, i.e., 8. Therefore, vertex 4 is selected.
Since vertex 4 is selected, so we will consider all the direct paths from the vertex 4. The direct
paths from vertex 4 are 4 to 0, 4 to 1, 4 to 8, and 4 to 5. Since the vertices 0 and 1 have already been
selected so we will not consider the vertices 0 and 1. We will consider only two vertices, i.e., 8 and 5.
First, we consider the vertex 8. First, we calculate the distance between the vertex 4 and 8.
Consider the vertex 4 as 'x', and the vertex 8 as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (8 + 7) < ∞
= 15 < ∞
Since 15 is less than the infinity so we update d(8) from infinity to 15.
Now, we consider the vertex 5. First, we calculate the distance between the vertex 4 and 5.
Consider the vertex 4 as 'x', and the vertex 5 as 'y'.
Unit II
46
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (8 + 1) < ∞
=9<∞
Since 5 is less than the infinity, we update d(5) from infinity to 9.
Till now, three nodes have been selected, i.e., 0, 1, and 4. Now we have to compare the nodes
except the nodes 0, 1 and 4. The node 5 has the minimum value, i.e., 9. Therefore, vertex 5 is selected.
Since the vertex 5 is selected, so we will consider all the direct paths from vertex 5. The direct
paths from vertex 5 are 5 to 8, and 5 to 6.
First, we consider the vertex 8. First, we calculate the distance between the vertex 5 and
8. Consider the vertex 5 as 'x', and the vertex 8 as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (9 + 15) < 15
= 24 < 15
Since 24 is not less than 15 so we will not update the value d(8) from 15 to 24.
Now, we consider the vertex 6. First, we calculate the distance between the vertex 5 and 6.
Consider the vertex 5 as 'x', and the vertex 6 as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (9 + 2) < ∞<>
= 11 < ∞
First, we consider the vertex 2. Consider the vertex 6 as 'x', and the vertex 2 as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (11 + 4) < 12
= 15 < 12
Since 15 is not less than 12, we will not update d(2) from 12 to 15
Now we consider the vertex 3. Consider the vertex 6 as 'x', and the vertex 3 as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (11 + 14) < ∞
= 25 < ∞
Since 25 is less than ∞, so we will update d(3) from ∞ to 25.
Now we consider the vertex 7. Consider the vertex 6 as 'x', and the vertex 7 as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
Unit II
47
= (11 + 10) < ∞
= 22 < ∞
Since 22 is less than ∞ so, we will update d(7) from ∞ to 22.
Till now, nodes 0, 1, 4, 5, and 6 have been selected. Now we have to compare all the unvisited nodes,
i.e., 2, 3, 7, and 8. Since node 2 has the minimum value, i.e., 12 among all the other unvisited nodes.
Therefore, node 2 is selected. Since node 2 is selected, so we consider all the direct paths from node 2.
The direct paths from node 2 are 2 to 8, 2 to 6, and 2 to 3.
First, we consider the vertex 8. Consider the vertex 2 as 'x' and 8 as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (12 + 2) < 15
= 14 < 15
Since 16 is not less than 11 so we will not update d(6) from 11 to 16. Now,
we consider the vertex 3. Consider the vertex 2 as 'x' and 3 as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (12 + 7) < 25
= 19 < 25
Since 28 is not less than 21, so we will not update d(7) from 28 to 21.
Unit II
48
Example 2 – Directed Graph
Let's consider the directed graph.
Here, we consider A as a source vertex. A vertex is a source vertex so entry is filled with 0 while other
vertices filled with ∞. The distance from source vertex to source vertex is 0, and the
distance from the source vertex to other vertices is ∞. We
A B C D E
∞ ∞ ∞ ∞ ∞
Since 0 is the minimum value in the above table, so we select vertex A and added in the second row
shown as below:
A B C D E
A 0 ∞ ∞ ∞ ∞
As we can observe in the above graph that there are two vertices directly connected to the vertex
A, i.e., B and C. The vertex A is not directly connected to the vertex E, i.e., the edge is from E to A. Here we
can calculate the two distances, i.e., from A to B and A to C. The same formula will be used as in the
previous problem.
A B C D E
A 0 ∞ ∞ ∞ ∞
10 5 ∞ ∞
As we can observe in the third row that 5 is the lowest value so vertex C will be added in the third
row. We have calculated the distance of vertices B and C from A. Now we will compare the vertices to
find the vertex with the lowest value. Since the vertex C has the minimum value, i.e., 5 so vertex C will be
selected. Since the vertex C is selected, so we consider all the direct paths
Unit II
49
from the vertex C. The direct paths from the vertex C are C to B, C to D, and C to E. First, we consider
the vertex B. We calculate the distance from C to B. Consider vertex C as 'x' and vertex B as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (5 + 3) < ∞
=8<∞
Since 8 is less than the infinity so we update d(B) from ∞ to 8. Now the new row will be inserted in
which value 8 will be added under the B column.
A B C D E
A 0 ∞ ∞ ∞ ∞
10 5 ∞ ∞
We consider the vertex D. We calculate the distance from C to D. Consider vertex C as 'x' and vertex D
as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (5 + 9) < ∞
= 14 < ∞
Since 14 is less than the infinity so we update d(D) from ∞ to 14. The value 14 will be added under
the D column.
A B C D E
A 0 ∞ ∞ ∞ ∞
C 10 5 ∞ ∞
8 14
We consider the vertex E. We calculate the distance from C to E. Consider vertex C as 'x' and vertex E
as 'y'.
If d(x) + c(x, y) < d(y) then
d(y) = d(x) + c(x, y)
= (5 + 2) < ∞
=7<∞
Since 14 is less than the infinity so we update d(D) from ∞ to 14. The value 14 will be added under
the D column.
Unit II
50
A B C D E
A 0 ∞ ∞ ∞ ∞
C 10 5 ∞ ∞
8 14 7
As we can observe in the above table that 7 is the minimum value among 8, 14, and 7. Therefore, the
vertex E is added on the left as shown in the below table:
A B C D E
A 0 ∞ ∞ ∞ ∞
C 10 5 ∞ ∞
E 8 14 7
The vertex E is selected so we consider all the direct paths from the vertex E. The direct paths from the
vertex E are E to A and E to D. Since the vertex A is selected, so we will not consider the path from E to A.
Since 13 is less than the infinity so we update d(D) from ∞ to 13. The value 13 will be added under
the D column.
A B C D E
A 0 ∞ ∞ ∞ ∞
C 10 5 ∞ ∞
E 8 14 7
B 8 13
Unit II
51
The value 8 is minimum among 8 and 13. Therefore, vertex B is selected. The direct path from B is B to
D.
Since 9 is less than 13 so we update d(D) from 13 to 9. The value 9 will be added under the D column.
A B C D E
A 0 ∞ ∞ ∞ ∞
C 10 5 ∞ ∞
E 8 14 7
B 8 13
D 9
2.6.2.2.2 Pseudocode
Bellman ford algorithm follows the dynamic programming approach by
overestimating the length of the path from the starting vertex to all other vertices. And then it
starts relaxing the estimates by discovering the new paths which are shorter than the
previous ones. This process is followed by all the vertices for N-1 times for finding the
optimized result.The pseudocode of the algorithm is the following:
Unit II
52
Input : A graph representing the network; and a source node, s Output :
Shortest path from s to all other nodes.
1. Initialize distances from s to all nodes as infinite (∞); distance to itself as 0; an array
dist[] of size |V| (number of nodes) with all values as ∞ except dist[s].
2. Calculate the shortest distances iteratively. Repeat |V|- 1 times for each node
except s −
Repeat for each edge connecting vertices u and v −
If dist[v] > (dist[u] + weight of edge u-v), Then Update
dist[v] = dist[u] + weight of edge u-v
3. The array dist[] contains the shortest path from s to every other node.
Solution
Step 1: Step 2:
Select the source vertex with path value 0 and Visit the neighbouring edge from the
all other vertices as infinity. source vertex and relax the path length of the
neighbouring vertex if the new calculated
path length is smaller than the previous
path length
Step 3:
This process must be followed N-1 times where N is the total number of vertices. This is
because in the worst-case scenario any vertex’s path length can be changed to an even smaller
path length for N times.
Unit II
53
Therefore after N-1 iterations, we find our new path lengths and we can check if the
graph has a negative cycle or not.
Q R S T
O ∞ ∞ ∞ ∞
O 2 4 ∞ ∞
O 2 4 4 7
O 2 4 2 7
O 2 4 2 7
Example 2:
Relax compares a destination weight with addition of weight of source vertex and
weight of weight and sets which is smaller, given in figure below:
Unit II
54
Solution:
Example 2
Transitive closure of the graph
0 1 2 3
0 1 1 1 1
1 1 1 1 1
2 1 1 1 1
3 0 0 0 1
Example 3
Transitive closure of the graph
1 2 3 4
1 1 0 1 0
2 1 1 0 1
3 0 0 1 0
4 0 1 0 1
Unit II
56
Digraph Weight Matrix Distance Matrix
2.6.2.3.3 Pseudocode
1. Initialize the solution matrix same as the input graph matrix as a first step.
2. Update the solution matrix by considering all vertices as an intermediate vertex.
3. Pick all vertices one by one and updates all shortest paths which include the picked
vertex as an intermediate vertex in the shortest path.
4. When we pick vertex number k as an intermediate vertex, we already have
considered vertices {0, 1, 2, .. k-1} as intermediate vertices.
5. For every pair (i, j) of the source and destination vertices respectively, there are two
possible cases.
• k is not an intermediate vertex in shortest path from i to j. We keep the value
of dist[i][j] as it is.
• k is an intermediate vertex in shortest path from i to j. Update the value of
dist[i][j] as dist[i][k] + dist[k][j]
if dist[i][j] > dist[i][k] + dist[k][j]
Example 1:
Using Floyd Warshall Algorithm, find the shortest path distance between every pair of
vertices.
Solution:
Step-01:
• Remove all the self loops and parallel edges (keeping the lowest weight edge) from
the graph.
• In the given graph, there are neither self edges nor parallel edges.
Unit II
57
Step-02:
• Write the initial distance matrix. It represents the distance between every pair of
vertices in the form of given weights.
• For diagonal elements (representing self-loops), distance value = 0.
• Vertices having a direct edge between them, distance = weight of that edge.
• For vertices having no direct edge between them, distance value = ∞.
Given Digraph Initial distance matrix
Step-03:
Using Floyd Warshall Algorithm, write the following 4 matrices-
Unit II
58
Example 2:
Example 3:
Given Digraph Initial distance matrix
Unit II
59
2.6.2.4. Python program for shortest path algorithm
import matplotlib.pyplot as plt
# importing networkx
import networkx as nx
import pylab
# Create an empty Undirected Weighted Graph
G = nx.Graph()
nodes_list = [1, 2, 3, 4, 5, 6, 7]
G.add_nodes_from(nodes_list)
plt.figure()
pos = nx.spring_layout(G)
weight_labels = nx.get_edge_attributes(G,'weight')
nx.draw(G,pos,font_color = 'white', node_shape = 's', with_labels = True,)
nx.draw_networkx_edge_labels(G,pos,edge_labels=weight_labels)
Unit II
60
pos = nx.planar_layout(G)
#Give us the shortest paths from node 1 using the weights from the edges.
p1 = nx.shortest_path(G, source=1, weight="weight")
# This will give us the length of the shortest path from node 1 to node 6.
length = nx.shortest_path_length(G, source=1, target=6, weight="weight")
Output:
All shortest paths from 1: {1: [1], 2: [1, 4, 2], 4: [1, 4], 5: [1, 4, 5], 7:
[1, 4, 7], 3: [1, 4, 5, 3], 6: [1, 4, 7, 6]}
Shortest path from 1 to 6: [1, 4, 7, 6]
Length of the shortest path: 11
Negative Single
Algorithm All source Time complexity Space Complexity
weight source
Dijkstra √ O(|E| + V log|V|) O(|V|2)
Bellman-Ford √ √ O(|V|.|E|) O(|V|2)
Floyd Warshall √ √ O(|V|3) O(|V|3)
Unit II
61
Flow networks
Definition:
A flow network is defined as a directed graph where each edge has:
→ Capacity (a non-negative real number)
→ Flow (a non-negative real number that is less than or equal to the capacity).
Additionally, there are two special nodes in the network:
→ Source node where the flow enters the network
→ Sink node where the flow leaves the network.
Goal:
→ To find the maximum amount of flow that can be sent from the source to the sink while
satisfying the capacity constraints.
In the context of flow networks, augmenting means increasing the flow along a path in the
network. An augmenting path is a simple path from the source node to the sink node,
along which there is available capacity in all edges. An augmenting path can be used to
increase the flow from the source to the sink, by sending additional flow along the path.
Applications:
Flow networks have numerous applications:
→ Transportation networks
→ Communication networks
→ Electrical networks
→ Water distribution networks.
They can be used to optimize the flow of resources, minimize congestion, and improve
efficiency in various systems.
Unit II
62
In a flow network, there are two distinguished vertices: the source s and the sink t. The source
is where the flow enters the network, and the sink is where the flow leaves the network.
There are no incoming edges to the source and no outgoing edges from the sink.
To represent a flow network, we can use a graph G(V, E) with a capacity function
c:E→R+. Additionally, we can add a flow function f:E→R to keep track of the flow
through each edge. The value of the flow function f(e) represents the amount of flow
currently passing through the edge e.
Fulkerson algorithm
The Ford-Fulkerson algorithm is an algorithm used to find the maximum flow in a flow
network. It is named after L.R. Ford Jr. and D.R. Fulkerson who published the algorithm in
1956.
Unit II
63
Problems on Ford-Fulkerson algorithm
Problem 1:
Solution:
Unit II
64
Problem 2:
Unit II
65
Solution
Step 1 Step 2
Select any arbitrary path from S to T. In this The minimum capacity among the three
step, we have selected path S-A-B-T edges is 2 (B-T). Based on this, update the
flow/capacity for each path.
Step 3 Step 4
Select another path S-D-C-T. The minimum Update the capacities according to this.
capacity among these edges is 3 (S-D)
Step 5 Step 6
Now, let us consider the reverse-path B-D as Updating the capacities.
well. Selecting path S-A-B-D-C-T. The
minimum residual capacity among the
edges is 1 (D-C).
The capacity for forward and reverse paths are considered separately.
Adding all the flows = 2 + 3 + 1 = 6, which is the maximum possible flow on the flow network.
Unit II
66
# Python program for Ford-Fulkerson algorithm
# Create a directed graph representing the flow network
G = nx.DiGraph()
# Find the maximum flow from 'A' to 'D' using the Ford-Fulkerson algorithm
source = 'A'
sink = 'D'
max_flow_value, flow_dict = nx.maximum_flow(G, source, sink)
Execution:
Maximum flow from A to D is 4
import networkx as nx
import matplotlib.pyplot as plt
# Print the intermediate steps of the algorithm and draw the corresponding g
raphs
for i in range(1, flow_value+1):
H = G.copy()
for u, nbrs in flow_dict.items():
for v, flow in nbrs.items():
if flow >= i:
H[u][v]['color'] = 'r'
H[u][v]['flow'] = flow - i
else:
H[u][v]['color'] = 'k'
H[u][v]['flow'] = 0
pos = nx.spring_layout(H)
edge_colors = [H[u][v]['color'] for u, v in H.edges()]
edge_labels = {(u, v): f"{H[u][v]['flow']}/{G[u][v]['capacity']}" for u,
v in H.edges()}
nx.draw(H, pos, with_labels=True, edge_color=edge_colors)
nx.draw_networkx_edge_labels(H, pos, edge_labels=edge_labels)
plt.title(f"Residual graph after iteration {i}")
plt.show()
Unit II
68
The maximum flow is 5.
There are M job applicants and N jobs. Each applicant has a subset of jobs that he/she is
interested in. Each job opening can only accept one applicant and a job applicant can be
Unit II
69
appointed for only one job. Find an assignment of jobs to applicants in such that as many
applicants as possible get jobs.”
Applications
• Assigning tasks to workers
• Matching organ donors with recipients
• Matching job seekers with potential employers.
Finding the maximum bipartite matching can be done using various algorithms,
including the Hopcroft-Karp algorithm, Edmonds' algorithm, or the Ford-Fulkerson
algorithm.
Maximum Bipartite Matching (MBP) problem can be solved by converting it into a flow
network
• Build a Flow Network: There must be a source and sink in a flow network. So we add a
source and add edges from source to all applicants. Similarly, add edges from all jobs
to sink. The capacity of every edge is marked as 1 unit.
• Find the maximum flow: We use Ford-Fulkerson algorithm to find the maximum flow
in the flow network built in above step. The maximum flow is actually the MBP we
are looking for.
Algorithm
bipartiteMatch(u, visited, assign)
Input: Starting node, visited list to keep track, assign the list to assign node with
another node.
Unit II
70
Output − Returns true when a matching for vertex u is possible.
Begin
for all vertex v, which are adjacent with u, do if
v is not visited, then
mark v as visited
if v is not assigned, or bipartiteMatch(assign[v], visited, assign) is true, then assign[v]
:= u
return true
done
return false
End
maxMatch(graph)
Input − The given graph.
Output − The maximum number of the match.
Begin
initially no vertex is assigned
count := 0
for all applicant u in M, do
make all node as unvisited
if bipartiteMatch(u, visited, assign), then
increase count by 1
done
End
Unit II
71