0% found this document useful (0 votes)
69 views49 pages

Assignment2 Last

The document discusses spanning trees and minimum spanning trees. It provides definitions and examples of spanning trees and minimum spanning trees. It then describes Kruskal's algorithm and Prim's algorithm for finding minimum spanning trees in detail, including pseudocode for Kruskal's algorithm.

Uploaded by

Legesse Samuel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
69 views49 pages

Assignment2 Last

The document discusses spanning trees and minimum spanning trees. It provides definitions and examples of spanning trees and minimum spanning trees. It then describes Kruskal's algorithm and Prim's algorithm for finding minimum spanning trees in detail, including pseudocode for Kruskal's algorithm.

Uploaded by

Legesse Samuel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 49

Wachemo University

Institute Of Technology
Department Of Computer Science
2014 E.C MSc 1stYear Regular Program

Advanced Analysis of Algorithm

Lab Manual

Prepared By
Legesse Samuel

WCU
Table of Contents
1. Spanning Tree and Minimum Spanning Tree.......................................................................................1
A. What is spanning tree?..............................................................................................................2
A. What is minimum Spanning Tree?...........................................................................................3
1.1What is Kruskal's Algorithm?..............................................................................................................5
1.2 What is Prim’s Algorithm?...............................................................................................................10
2. Single-Source Shortest Paths.............................................................................................................15
2.1 Bellman-Ford algorithm...................................................................................................................15
2.2 Single-source shortest paths in directed acyclic graphs...................................................................22
2.3 Dijkstra's Algorithm.........................................................................................................................28
3. All-Pairs Shortest Paths......................................................................................................................35
3.1 Shortest paths and matrix multiplication........................................................................................35
3.2 The Floyd-Warshall algorithm..........................................................................................................42
3.3 Johnson’s algorithm for sparse graphs......................................................................................45

WCU
1. Spanning Tree and Minimum Spanning Tree

Before we learn about spanning trees, we need to understand two graphs: undirected graphs and
connected graphs.

An undirected graph is a graph in which the edges do not point in any direction (i.e. the edges
are bidirectional).

Example of Undirected Graph

A B

C D

A connected graph is a graph in which there is always a path from a vertex to any other vertex.

B
Connected Graph
A

C
D

1
A. What is spanning tree?
 A spanning tree is a sub-graph of an undirected connected graph, which includes all the
vertices of the graph with a minimum possible number of edges. If a vertex is missed,
then it is not a spanning tree.
 The edges may or may not have weights assigned to them.
 The total number of spanning trees with n vertices that can be created from a complete
graph is equal to nn-2.
 If we have n=4, the maximum number of possible spanning trees is equal to 4 4-2 = 16.
Thus, 16 spanning trees can be formed from a complete graph with 4 vertices.

Example of a Spanning Tree

Let's understand the spanning tree with examples below:

Normal Graph

Let the original graph be: Some of the possible spanning trees that can be created from the
above graph are:

A spanning tree

2
A spanning tree

A. What is minimum Spanning Tree?


A minimum spanning tree is a spanning tree in which the sum of the weight of the edges is as
minimum as possible.

General Properties of Spanning Tree

We now understand that one graph can have more than one spanning tree. Following are
a few properties of the spanning tree connected to graph G −
A connected graph G can have more than one spanning tree.
All possible spanning trees of graph G, have the same number of edges and vertices.
The spanning tree does not have any cycle (loops).
Removing one edge from the spanning tree will make the graph disconnected, i.e. the
spanning tree is minimally connected.
Adding one edge to the spanning tree will create a circuit or loop, i.e. the spanning tree
is maximally acyclic.

Let's understand the above definition with the help of the example below.

The initial graph is:

Weighted tree

3
The possible spanning trees from the above graph are:

Minimum spanning tree 1 Minimum spanning tree 2

Minimum spanning tree 3 Minimum spanning tree 4

4
The minimum spanning tree from the above spanning tree is

The minimum spanning tree from a graph is found using the following algorithms:

1.1 Kruskal's Algorithm


1.2 Prim's Algorithm

1.1 What is Kruskal's Algorithm?

Kruskal's algorithm is a minimum spanning tree algorithm that takes a graph as input and finds
the subset of the edges of that graph whichform a tree that includes every vertex

How Kruskal's algorithm works

It falls under a class of algorithms called greedy algorithms that find the local optimum in the
hopes of finding a global optimum.

We start from the edges with the lowest weight and keep adding edges until we reach our goal.

The steps for implementing Kruskal's algorithm are as follows:

 Sort all the edges from low weight to high


 Take the edge with the lowest weight and add it to the spanning tree. If adding the edge
created a cycle, then reject this edge.
 Keep adding edges until we reach all vertices.

5
Example of Kruskal's algorithm

Start with a weighted graph

Choose the edge with the least weight, if there are more than 1, choose anyone

Choose the next shortest edge and add it

6
Choose the next shortest edge that doesn’t create a cycle and add it

Choose the next shortest edge that doesn’t create a cycle and add it

Repeat until you have spanning tree

7
Kruskal's Algorithm Code
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

#define edge pair<int, int>

class Graph {
private:
vector<pair<int, edge>> G; // graph
vector<pair<int, edge>> T; // mst
int *parent;
int V; // number of vertices/nodes in graph
public:
Graph(int V);
void AddWeightedEdge(int u, int v, int w);
intfind_set(inti);
void union_set(int u, int v);
void kruskal();
void print();
};
Graph::Graph(int V) {
parent = new int[V];

//i 0 1 2 3 4 5
//parent[i] 0 1 2 3 4 5
for (inti = 0; i < V; i++)
parent[i] = i;

G.clear();
T.clear();
}
void Graph::AddWeightedEdge(int u, int v, int w) {
G.push_back(make_pair(w, edge(u, v)));
}
int Graph::find_set(inti) {
// If i is the parent of itself
if (i == parent[i])
return i;
else
// Else if i is not the parent of itself
// Then i is not the representative of his set,
// so we recursively call Find on its parent
return find_set(parent[i]);

8
}

void Graph::union_set(int u, int v) {


parent[u] = parent[v];
}
void Graph::kruskal() {
inti, uRep, vRep;
sort(G.begin(), G.end()); // increasing weight
for (i = 0; i<G.size(); i++) {
uRep = find_set(G[i].second.first);
vRep = find_set(G[i].second.second);
if (uRep != vRep) {
T.push_back(G[i]); // add to tree
union_set(uRep, vRep);
}
}
}
void Graph::print() {
cout<< "Edge :"
<< " Weght" <<endl;
for (inti = 0; i<T.size(); i++) {
cout<< T[i].second.first<< " - " << T[i].second.second<< " : "
<< T[i].first;
cout<<endl;

}
}
int main() {
Graph g(6);
g.AddWeightedEdge(0, 1, 4);
g.AddWeightedEdge(0, 2, 4);
g.AddWeightedEdge(1, 2, 2);
g.AddWeightedEdge(1, 0, 4);
g.AddWeightedEdge(2, 0, 4);
g.AddWeightedEdge(2, 1, 2);
g.AddWeightedEdge(2, 3, 3);
g.AddWeightedEdge(2, 5, 2);
g.AddWeightedEdge(2, 4, 4);
g.AddWeightedEdge(3, 2, 3);
g.AddWeightedEdge(3, 4, 3);
g.AddWeightedEdge(4, 2, 4);
g.AddWeightedEdge(4, 3, 3);
g.AddWeightedEdge(5, 2, 2);
g.AddWeightedEdge(5, 4, 3);
g.kruskal();
g.print();

9
cout<<"The minimum cost is:- 2+2+3+3+4= 14 ";
return 0;
}

Output

Kruskal's vs Prim's Algorithm

Prim's algorithm is another popular minimum spanning tree algorithm that uses a different
logic to find the MST of a graph. Instead of starting from an edge, Prim's algorithm starts from a
vertex and keeps adding lowest-weight edges which aren't in the tree, until all vertices have been
covered.

10
1.2 What is Prim’s Algorithm?

Prim’s algorithm is a greedy approach method for minimum spanning tree which finds the local
optimum path to obtain the global optimum solution.

Prim's algorithm to find minimum cost spanning tree (as Kruskal's algorithm) uses the greedy
approach. Prim's algorithm shares a similarity with the shortest path first algorithms.

Prim's algorithm is a minimum spanning tree algorithm that takes a graph as input and finds the
subset of the edges of that graph which

Form a tree that includes every vertex and has the minimum sum of weights among all the trees
that can be formed from the graph

How Prim's algorithm works

 It falls under a class of algorithms called greedy algorithms that find the local optimum in
the hopes of finding a global optimum.
 We start from one vertex and keep adding edges with the lowest weight until we reach
our goal.

The steps for implementing Prim's algorithm for minimum spanning tree are as follows:

Initialize the minimum spanning tree with a vertex chosen at random.


Find all the edges that connect the tree to new vertices, find the minimum and add it to
the tree
Keep repeating step 2 until we get a minimum spanning tree

The below graph used to do minimum spanning tree by using prim algorithm.

11
Now we will understand this algorithm through the example where we will see the each step to
select edges to form the minimum spanning tree (MST) using prim’s algorithm.

Here we look that the cost of the minimum spanning tree is 99 and the number of edges in
minimum spanning tree is 6.

12
In above diagram we take alphabet A, B, C, D, E, F, G for vertex which is similar to 0,1,2,3,4,5,6
for vertex and we will see 0,1,2,3,4,5,6 in coding section.

PRIM’S Algorithm Code

#include <iostream>
#include<bits/stdc++.h>
#include <cstring>
usingnamespacestd;
// number of vertices in graph
#define V 7
// create a 2d array of size 7x7
//for adjacency matrix to represent graph
intmain(){
// create a 2d array of size 7x7
//for adjacency matrix to represent graph
int G[V][V] = {
{0,28,0,0,0,10,0},
{28,0,16,0,0,0,14},
{0,16,0,12,0,0,0},
{0,0,12,22,0,18},
{0,0,0,22,0,25,24},
{10,0,0,0,25,0,0},
{0,14,0,18,24,0,0}
};
int edge; // number of edge
// create an array to check visited vertex
int visit[V];
//initialise the visit array to false
for(inti=0;i<V;i++){
visit[i]=false;
}
// set number of edge to 0
edge = 0;
// the number of edges in minimum spanning tree will be
// always less than (V -1), where V is the number of vertices in
//graph
// choose 0th vertex and make it true
visit[0] = true;
int x; // row number
int y; // col number
// print for edge and weight
cout<<"Edge"<<" : "<<"Weight";

13
cout<<endl;
while(edge < V - 1){//in spanning tree consist the V-1 number of edges
//For every vertex in the set S, find the all adjacent vertices
//, calculate the distance from the vertex selected.
// if the vertex is already visited, discard it otherwise
//choose another vertex nearest to selected vertex.
int min = INT_MAX;
x = 0;
y = 0;
for(inti = 0; i < V; i++){
if(visit[i]){
for(int j = 0; j < V; j++){
if(!visit[j]&& G[i][j]){ // not in selected and there is an edge
if(min > G[i][j]){
min = G[i][j];
x = i;
y = j;
}
}
}
}
}
cout<< x <<" ---> "<< y <<" : "<< G[x][y];
cout<<endl;
visit[y] = true;
edge++;
}
cout<<"The minimum cost is = 10+25+22+12+16+14 = 99 ";
return 0;
}

Output

14
2. Single-Source Shortest Paths

What is Single-Source Shortest Paths?

The Single-Source Shortest Path (SSSP) problem consists of finding the shortest paths between a
given vertex v and all other vertices in the graph.

Single Source Shortest Path is the shortest path to each of the n vertices of the digraph from a
given source vertex.

In graph theory, the shortest path problem is the problem of finding a path between
two vertices (or nodes) in a graph such that the sum of the weights of its constituent edges is
minimized.
The Single-Pair Shortest Path (SPSP) problem consists of finding the shortest path between a
single pair of vertices. This problem is mostly solved using Dijkstra algorithm, the Bellman-
Ford algorithm and so on though in this case a single result is kept and other shortest paths are
discarded.

2.1 Bellman-Ford algorithm

2.1.1 What is Bellman-Ford Algorithm?

The Bellman–Ford algorithm is an algorithm that computes shortest paths from a single
source vertex to all of the other vertices in a weighted digraph.
It is slower than Dijkstra's algorithm for the same problem, but more versatile, as it is
capable of handling graphs in which some of the edge weights are negative numbers.
Bellman Ford algorithm helps us find the shortest path from a vertex to all other vertices of a
weighted graph.
It is similar to Dijkstra's algorithm but it can work with graphs in which edges can have negative
weights.
The Bellman-Ford algorithm is a very popular algorithm used to find the shortest
path from one node to all the other nodes in a weighted graph.
Bellman ford algorithm is a single-source shortest path algorithm.
In contrast to Dijkstra algorithm, bellman ford algorithm guarantees the correct answer
even if the weighted graph contains the negative weight values.

15
Algorithm

1. List down all the edges of the graph. This can be done easily if the graph is represented
by an adjacency list.

2. Calculate the number of iterations with “V - 1”. The number of iterations will be equal to
the number of vertices because the shortest distance to an edge can be adjusted V -
1 times at maximum.

3. Start with an arbitrary vertex and assign it the minimum distance of zero. All other nodes
should be assigned infinity since we are exaggerating the actual distances.

4. In each iteration, update the distance for each edge if the new distance is smaller than the
one assigned before. The distance to each node will be the cumulative distance from the
starting node to this particular node.

5. We need to consider all the iterations to make sure that all possible paths are considered.
If we do this, we will end up with the shortest distance.

16
Let all edges are processed in the following order: (B, E), (D, B), (B, D), (A, B), (A, C), (D,
C), (B, C), (E, D). We get the following distances when all edges are processed the first time.
The first row shows initial distances. The second row shows distances when edges (B, E), (D,
B), (B, D) and (A, B) are processed. The third row shows distances when (A, C) is processed.
The fourth row shows when (D, C), (B, C) and (E, D) are processed.

17
The first iteration guarantees to give all shortest paths which are at most 1 edge long. We get
the following distances when all edges are processed second time (The last row shows final
values).

The second iteration guarantees to give all shortest paths which are at most 2 edges long. The
algorithm processes all edges 2 more times. The distances are minimized after the second
iteration, so third and fourth iterations don’t update the distances.

18
Bellman-Ford's Algorithm Code

// A C++ program for Bellman-Ford's single source


// shortest path algorithm.
#include <bits/stdc++.h>

// a structure to represent a weighted edge in graph


struct Edge {
intsrc, dest, weight;
};

// a structure to represent a connected, directed and


// weighted graph
struct Graph {
// V-> Number of vertices, E-> Number of edges
int V, E;

// graph is represented as an array of edges.


struct Edge* edge;
};

// Creates a graph with V vertices and E edges


struct Graph* createGraph(int V, int E)
{
struct Graph* graph = new Graph;
graph->V = V;
graph->E = E;
graph->edge = new Edge[E];
return graph;
}

// A utility function used to print the solution


void printArr(intdist[], int n)
{
printf("Vertex Distance from Source\n");
for (inti = 0; i < n; ++i)
printf("%d \t\t %d\n", i, dist[i]);
}

// The main function that finds shortest distances from src


// to all other vertices using Bellman-Ford algorithm. The
// function also detects negative weight cycle
void BellmanFord(struct Graph* graph, intsrc)
{
int V = graph->V;

19
int E = graph->E;
intdist[V];

// Step 1: Initialize distances from src to all other


// vertices as INFINITE
for (inti = 0; i < V; i++)
dist[i] = INT_MAX;
dist[src] = 0;

// Step 2: Relax all edges |V| - 1 times. A simple


// shortest path from src to any other vertex can have
// at-most |V| - 1 edges
for (inti = 1; i <= V - 1; i++) {
for (int j = 0; j < E; j++) {
int u = graph->edge[j].src;
int v = graph->edge[j].dest;
int weight = graph->edge[j].weight;
if (dist[u] != INT_MAX
&&dist[u] + weight <dist[v])
dist[v] = dist[u] + weight;
}
}

// Step 3: check for negative-weight cycles. The above


// step guarantees shortest distances if graph doesn't
// contain negative weight cycle. If we get a shorter
// path, then there is a cycle.
for (inti = 0; i < E; i++) {
int u = graph->edge[i].src;
int v = graph->edge[i].dest;
int weight = graph->edge[i].weight;
if (dist[u] != INT_MAX
&&dist[u] + weight <dist[v]) {
printf("Graph contains negative weight cycle");
return; // If negative cycle is detected, simply
// return
}
}

printArr(dist, V);

return;
}

// Driver program to test above functions


int main()

20
{
/* Let us create the graph given in above example */
int V = 5; // Number of vertices in graph
int E = 8; // Number of edges in graph
struct Graph* graph = createGraph(V, E);

// add edge 0-1 (or A-B in above figure)


graph->edge[0].src = 0;
graph->edge[0].dest = 1;
graph->edge[0].weight = -1;

// add edge 0-2 (or A-C in above figure)


graph->edge[1].src = 0;
graph->edge[1].dest = 2;
graph->edge[1].weight = 4;

// add edge 1-2 (or B-C in above figure)


graph->edge[2].src = 1;
graph->edge[2].dest = 2;
graph->edge[2].weight = 3;

// add edge 1-3 (or B-D in above figure)


graph->edge[3].src = 1;
graph->edge[3].dest = 3;
graph->edge[3].weight = 2;

// add edge 1-4 (or B-E in above figure)


graph->edge[4].src = 1;
graph->edge[4].dest = 4;
graph->edge[4].weight = 2;

// add edge 3-2 (or D-C in above figure)


graph->edge[5].src = 3;
graph->edge[5].dest = 2;
graph->edge[5].weight = 5;

// add edge 3-1 (or D-B in above figure)


graph->edge[6].src = 3;
graph->edge[6].dest = 1;
graph->edge[6].weight = 1;

// add edge 4-3 (or E-D in above figure)


graph->edge[7].src = 4;
graph->edge[7].dest = 3;
graph->edge[7].weight = -3;

21
BellmanFord(graph, 0);

return 0;
}

Output

2.2 Single-source shortest paths in directed acyclic graphs

What is a Single-source shortest path in directed acyclic graphs?

Single Source shortest path is basically the shortest distance between the source and other
vertices in the graph.

A weighted directed acyclic graph is a graph in which each edge has a weight and is directed
from one vertex to another, such that following those directions will never form a closed loop.

We can find the shortest path from the source to every other vertex by relaxing the edges of the
weighted directed acyclic graph G= (V, E) according to the topological sort of its vertices.

The topological order of the Directed acyclic graph is linear ordering in which, whenever we
have an edge from u to v, the ordering visits u before v. For example, the vertices of the graph
represent the tasks to be performed and the edges represent constraints that one task must be
performed before an earlier task. Here, the order in which we perform the tasks is known as the
topological order.

22
Algorithm
Following is complete algorithm for finding shortest distances.
1) Initialize dist [] = {INF, INF,} and dist[s] = 0 where s is the source vertex.
2) Create a topological order of all vertices.
3) Do following for every vertex u in topological order.
Do following for every adjacent vertex v of u
if (dist[v] >dist[u] + weight (u, v))
dist[v] = dist[u] + weight (u, v)

23
24
Directed Acyclic Graphs Code
// C++ program to find single source shortest paths for Directed Acyclic Graphs
#include<iostream>
#include <bits/stdc++.h>
#define INF INT_MAX
using namespace std;

// Graph is represented using adjacency list. Every node of adjacency list


// contains vertex number of the vertex to which edge connects.

class AdjListNode
{
int v;
int weight;
public:
AdjListNode(int _v, int _w) { v = _v; weight = _w;}
intgetV() { return v; }
intgetWeight() { return weight; }
};

// Class to represent a graph using adjacency list representation


class Graph
{
int V; // No. of vertices'

// Pointer to an array containing adjacency lists


list<AdjListNode> *adj;

// A function used by shortestPath


void topologicalSortUtil(int v, bool visited[], stack<int>&Stack);
public:
Graph(int V); // Constructor

// function to add an edge to graph


void addEdge(int u, int v, int weight);

// Finds shortest paths from given source vertex


void shortestPath(int s);
};

Graph::Graph(int V)
{
this->V = V;
adj = new list<AdjListNode>[V];
}

25
void Graph::addEdge(int u, int v, int weight)
{
AdjListNode node(v, weight);
adj[u].push_back(node); // Add v to u's list
}

// A recursive function used by shortestPath. See below link for details


void Graph::topologicalSortUtil(int v, bool visited[], stack<int>&Stack)
{
// Mark the current node as visited
visited[v] = true;

// Recur for all the vertices adjacent to this vertex


list<AdjListNode>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
{
AdjListNode node = *i;
if (!visited[node.getV()])
topologicalSortUtil(node.getV(), visited, Stack);
}

// Push current vertex to stack which stores topological sort


Stack.push(v);
}

// The function to find shortest paths from given vertex.


void Graph::shortestPath(int s)
{
stack<int> Stack;
intdist[V];

// Mark all the vertices as not visited


bool *visited = new bool[V];
for (inti = 0; i < V; i++)
visited[i] = false;

// Call the recursive helper function to store Topological Sort


// starting from all vertices one by one
for (inti = 0; i < V; i++)
if (visited[i] == false)
topologicalSortUtil(i, visited, Stack);

// Initialize distances to all vertices as infinite and distance


// to source as 0
for (inti = 0; i < V; i++)
dist[i] = INF;

26
dist[s] = 0;

// Process vertices in topological order


while (Stack.empty() == false)
{
// Get the next vertex from topological order
int u = Stack.top();
Stack.pop();

// Update distances of all adjacent vertices


list<AdjListNode>::iterator i;
if (dist[u] != INF)
{
for (i = adj[u].begin(); i != adj[u].end(); ++i)
if (dist[i->getV()] >dist[u] + i->getWeight())
dist[i->getV()] = dist[u] + i->getWeight();
}
}

// Print the calculated shortest distances


for (inti = 0; i < V; i++)
(dist[i] == INF)? cout<< "INF ": cout<<dist[i] << " ";
}

// Driver program to test above functions


int main()
{
// Create a graph given in the above diagram. Here vertex numbers are
// 0, 1, 2, 3, 4, 5 with following mappings:
// 0= r, 1=s, 2=t, 3= x, 4= y, 5= z
Graph g(6);
g.addEdge(0, 1, 5);
g.addEdge(0, 2, 3);
g.addEdge(1, 3, 6);
g.addEdge(1, 2, 2);
g.addEdge(2, 4, 4);
g.addEdge(2, 5, 2);
g.addEdge(2, 3, 7);
g.addEdge(3, 4, -1);
g.addEdge(4, 5, -2);

int s = 1;
cout<< "Following are shortest distances from source " << s <<" n";
g.shortestPath(s);
return 0;
}

27
Output

2.3 Dijkstra's Algorithm

What is Dijkstra's Algorithm?


An algorithm that is used for finding the shortest distance, or path, from starting node to
target node in a weighted graph is known as Dijkstra’s Algorithm.
Dijkstra's algorithm solves the shortest-path problem for any weighted, directed
graph with non-negative weights.
Solves the single-source shortest path problem with non-negative edge weight.
How to Implement the Dijkstra Algorithm?

Before preceding the step by step process for implementing the algorithm, let us consider some

essential characteristics of Dijkstra’s algorithm;

 Basically, the Dijkstra’s algorithm begins from the node to be selected, the source node, and it

examines the entire graph to determine the shortest path among that node and all the other nodes

in the graph.

 The algorithm maintains the track of the currently recognized shortest distance from each node to

the source code and updates these values if it identifies another shortest path.

 Once the algorithm has determined the shortest path amid the source code to another node, the

node is marked as “visited” and can be added to the path.

28
 This process is being continued till all the nodes in the graph have been added to the path, as this

way, a path gets created that connects the source node to all the other nodes following the

plausible shortest path to reach each node.

Algorithm
1) Create a set sptSet (shortest path tree set) that keeps track of vertices included in the
shortest-path tree, i.e., whose minimum distance from the source is calculated and finalized.
Initially, this set is empty.
2) Assign a distance value to all vertices in the input graph. Initialize all distance values as
INFINITE. Assign distance value as 0 for the source vertex so that it is picked first.
3) While sptSet doesn’t include all vertices
a) Pick a vertex u which is not there in sptSet and has a minimum distance value.
b) Include u to sptSet.
c) Update distance value of all adjacent vertices of u. To update the distance values, iterate
through all adjacent vertices. For every adjacent vertex v, if the sum of distance value of u
(from source) and weight of edge u-v, is less than the distance value of v, then update the
distance value of v.

29
Let us understand with the following example:

Step 1

The set sptSet is initially empty and distances assigned to vertices are {0, INF, INF, INF, INF,
INF, INF, INF} where INF indicates infinite. Now pick the vertex with a minimum distance
value. The vertex 0 is picked, include it in sptSet. So sptSet becomes {0}. After including 0
to sptSet, update distance values of its adjacent vertices. Adjacent vertices of 0 are 1 and 7.
The distance values of 1 and 7 are updated as 4 and 8. The following subgraph shows vertices
and their distance values, only the vertices with finite distance values are shown. The vertices
included in SPT are shown in green color.

30
Step 2

Pick the vertex with minimum distance value and not already included in SPT (not in
sptSET). The vertex 1 is picked and added to sptSet. So sptSet now becomes {0, 1}. Update
the distance values of adjacent vertices of 1. The distance value of vertex 2 becomes 12.

Step 3

Pick the vertex with minimum distance value and not already included in SPT (not in
sptSET). Vertex 7 is picked. So sptSet now becomes {0, 1, and 7}. Update the distance values
of adjacent vertices of 7. The distance value of vertex 6 and 8 becomes finite (15 and 9
respectively).

Step 4

Pick the vertex with minimum distance value and not already included in SPT (not in
sptSET). Vertex 6 is picked. So sptSet now becomes {0, 1, 7, 6}. Update the distance values
of adjacent vertices of 6. The distance value of vertex 5 and 8 are updated.

31
Step 5
We repeat the above steps until sptSet includes all vertices of the given graph. Finally, we get
the following Shortest Path Tree (SPT).

How to implement the above algorithm?

Dijkstra's Single source Shortest Path Algorithm Code

// A C++ program for Dijkstra's single source shortest path algorithm.

#include <iostream>
using namespace std;
#include <limits.h>

// Number of vertices in the graph


#define V 9

// A utility function to find the vertex with minimum distance value, from
// the set of vertices not yet included in shortest path tree
intminDistance(intdist[], boolsptSet[])
{

// Initialize min value


int min = INT_MAX, min_index;

32
for (int v = 0; v < V; v++)
if (sptSet[v] == false &&dist[v] <= min)
min = dist[v], min_index = v;

return min_index;
}

// A utility function to print the constructed distance array


void printSolution(intdist[])
{
cout<<"Vertex \t Distance from Source" <<endl;
for (inti = 0; i < V; i++)
cout <<i<< " \t\t"<<dist[i]<<endl;
}

// Function that implements Dijkstra's single source shortest path algorithm


// for a graph represented using adjacency matrix representation
void dijkstra(int graph[V][V], intsrc)
{
intdist[V]; // The output array. dist[i] will hold the shortest
// distance from src to i

boolsptSet[V]; // sptSet[i] will be true if vertex i is included in shortest


// path tree or shortest distance from src to i is finalized

// Initialize all distances as INFINITE and stpSet[] as false


for (inti = 0; i < V; i++)
dist[i] = INT_MAX, sptSet[i] = false;

// Distance of source vertex from itself is always 0


dist[src] = 0;

// Find shortest path for all vertices


for (int count = 0; count < V - 1; count++) {
// Pick the minimum distance vertex from the set of vertices not
// yet processed. u is always equal to src in the first iteration.
int u = minDistance(dist, sptSet);

// Mark the picked vertex as processed


sptSet[u] = true;

// Update dist value of the adjacent vertices of the picked vertex.


for (int v = 0; v < V; v++)

// Update dist[v] only if is not in sptSet, there is an edge from


// u to v, and total weight of path from src to v through u is

33
// smaller than current value of dist[v]
if (!sptSet[v] && graph[u][v] &&dist[u] != INT_MAX
&&dist[u] + graph[u][v] <dist[v])
dist[v] = dist[u] + graph[u][v];
}

// print the constructed distance array


printSolution(dist);
}

// driver program to test above function


int main()
{

/* Let us create the example graph discussed above */


int graph[V][V] = { { 0, 4, 0, 0, 0, 0, 0, 8, 0 },
{ 4, 0, 8, 0, 0, 0, 0, 11, 0 },
{ 0, 8, 0, 7, 0, 4, 0, 0, 2 },
{ 0, 0, 7, 0, 9, 14, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 10, 0, 0, 0 },
{ 0, 0, 4, 14, 10, 0, 2, 0, 0 },
{ 0, 0, 0, 0, 0, 2, 0, 1, 6 },
{ 8, 11, 0, 0, 0, 0, 1, 0, 7 },
{ 0, 0, 2, 0, 0, 0, 6, 7, 0 } };

dijkstra(graph, 0);

return 0;
}

Output

34
3. All-Pairs Shortest Paths

What is All-Pairs Shortest Paths?

The all pairs shortest path (APSP) problem is to compute shortest paths between all pairs of
vertices of a directed graph with nonnegative real numbers as edge costs. Focus is given on
shortest distances between vertices, as shortest paths can be obtained with a slight increase of
cost.

A directed graph is given by G = (V, E), where V = {1… n}, the set of vertices, and E is the set of
edges. The cost of edge (i, j) ∈ E is denoted by dij. The (n, n)-matrix D is one whose (i, j) element
is dij. It is assumed for simplicity that dij > 0 and dii = 0 for all i ≠ j. If there is no edge from i to j,
let dij=∞

3.1 Shortest paths and matrix multiplication

What is shortest paths and matrix multiplication?

This section presents a dynamic-programming algorithm for the all-pairs shortestpaths problem
on a directed graph G = (V, E). Each major loop of the dynamic program will invoke an
operation that is very similar to matrix multiplication, so that the algorithm will look like
repeated matrix multiplication. We shall start by developing a Θ (V4)-time algorithm for the all-
pairs shortest-paths problem and then improve its running time to Θ (V3 lg V).

Before proceeding, let us briefly recap the steps given in Dynamic Programming for developing
a dynamic-programming algorithm.

1. Characterize the structure of an optimal solution.

2. Recursively define the value of an optimal solution.

3. Compute the value of an optimal solution in a bottom-up fashion.

35
Floyd-Warhshall algorithm is the best algorithm to get shortest paths and matrix multiplication

This algorithm follows the dynamic programming approach to find the shortest paths.

Algorithm for Shortest paths and matrix multiplication

Let the given graph be:

Initial Graph

Follow the steps below to find the shortest path between all the pairs of vertices.

Create a matrix A0of dimension n*n where n is the number of vertices.

The row and the column are indexed as i and j respectively. i and j are the vertices of the graph.
Each cell A[i][j] is filled with the distance from the ithvertex to the jthvertex.

If there is no path from ith vertex to jth vertex, the cell is left as infinity.

36
Fill each cell with the distance between i th and jth vertex

Now, create a matrix A1 using matrix A0. The elements in the first column and the first row are
left as they are. The remaining cells are filled in the following way.

Let k be the intermediate vertex in the shortest path from source to destination. In this step, k is
the first vertex. A[i][j] is filled with (A[i][k]+A[k][j] if (A[i][j] > A[i][k] +A[k][j])

That is, if the direct distance from the source to the destination is greater than the path through
the vertex k, then the cell is filled with A[i][k]+ A[i][k].

In this step, k is vertex 1. We calculate the distance from source vertex to destination vertex
through this vertex k.

37
Calculate the distance from the source vertex to destination vertex through this vertex k

For example:For A1[2,4], the direct distance from vertex 2 to 4 is 4 and the sum of the distance
from vertex 2 to 4 through vertex (ie. from vertex 2 to 1 and from vertex 1 to 4) is 7.

Since 4<7, A0[2, 4] is filled with 4.

1. Similarly,A2 is created using A1. The elements in the second column and the second row
are left as they are.

In this step, k is the second vertex (i.e. vertex 2). The remaining steps are the same as in step 2.

Calculate the distance from the source vertex to destination vertex through this vertex 2
Similarly, A3 and A4 are also created.

38
Calculate the distance from the source vertex to destination vertex through this vertex 3

Calculate the distance from the source vertex to destination vertex through this vertex 4

2. A4 gives the shortest path between each pair of vertexes.

39
The above algorithm show that

n = no of vertices

A = matrix of dimension n*n

for k = 1 to n

for i = 1 to n

for j = 1 to n

Ak[i, j] = min (Ak-1[i, j], Ak-1[i, k] + Ak-1[k, j])


return A

Shortest paths and matrix multiplication Code


#include <iostream>
using namespace std;

// defining the number of vertices


#define nV 4

#define INF 999

void printMatrix(int matrix[][nV]);

// Implementing floydwarshall algorithm


void floydWarshall(int graph[][nV]) {
int matrix[nV][nV], i, j, k;

for (i = 0; i<nV; i++)


for (j = 0; j <nV; j++)
matrix[i][j] = graph[i][j];

// Adding vertices individually


for (k = 0; k <nV; k++) {
for (i = 0; i<nV; i++) {
for (j = 0; j <nV; j++) {
if (matrix[i][k] + matrix[k][j] < matrix[i][j])

40
matrix[i][j] = matrix[i][k] + matrix[k][j];
}
}
}
printMatrix(matrix);
}

void printMatrix(int matrix[][nV]) {


for (inti = 0; i<nV; i++) {
for (int j = 0; j <nV; j++) {
if (matrix[i][j] == INF)
printf("%4s", "INF");
else
printf("%4d", matrix[i][j]);
}
printf("\n");
}
}

int main() {
int graph[nV][nV] = {{0, 3, INF, 5},
{2, 0, INF, 4},
{INF, 1, 0, INF},
{INF, INF, 2, 0}};
floydWarshall(graph);
}

Output

41
3.2 The Floyd-Warshall algorithm

3.2.1 What is Floyd-Warshall algorithm?

The all pair shortest path algorithm is also known as Floyd-Warshall algorithm is used to find all
pair shortest path problem from a given weighted graph. As a result of this algorithm, it will
generate a matrix, which will represent the minimum distance from any node to all other nodes
in the graph.

At first the output matrix is same as given cost matrix of the graph. After that the output matrix
will be updated with all vertices k as the intermediate vertex.
The time complexity of this algorithm is O (V3); here V is the number of vertices in the graph.

Input − the cost matrix of the graph.

036∞∞∞∞
3021∞∞∞
620142∞
∞1102∞4
∞∞42021
∞∞2∞201
∞∞∞4110

42
Output − Matrix of all pair shortest path.

0345677
3021344
4201323
5110233
6332021
7423201
7433110

Algorithm of Floyd-Warshall

Input − the cost matrix of given Graph.


Output − Matrix to for shortest path between any vertex to any vertex.
Begin
for k := 0 to n, do
fori := 0 to n, do
for j := 0 to n, do
if cost[i,k] + cost[k,j] < cost[i,j], then
cost[i,j] := cost[i,k] + cost[k,j]
done
done
done
display the current cost matrix
End

43
The Floyd-Warshall Algorithm Code
#include<iostream>
#include<iomanip>
#define NODE 7
#define INF 999
using namespace std;
//Cost matrix of the graph
intcostMat[NODE][NODE] = {
{0, 3, 6, INF, INF, INF, INF},
{3, 0, 2, 1, INF, INF, INF},
{6, 2, 0, 1, 4, 2, INF},
{INF, 1, 1, 0, 2, INF, 4},
{INF, INF, 4, 2, 0, 2, 1},
{INF, INF, 2, INF, 2, 0, 1},
{INF, INF, INF, 4, 1, 1, 0}
};
void floydWarshal(){
int cost[NODE][NODE]; //defind to store shortest distance from any node to any node
for(inti = 0; i<NODE; i++)
for(int j = 0; j<NODE; j++)
cost[i][j] = costMat[i][j]; //copy costMatrix to new matrix
for(int k = 0; k<NODE; k++){
for(inti = 0; i<NODE; i++)
for(int j = 0; j<NODE; j++)
if(cost[i][k]+cost[k][j] < cost[i][j])
cost[i][j] = cost[i][k]+cost[k][j];
}
cout<< "The matrix:" <<endl;
for(inti = 0; i<NODE; i++){
for(int j = 0; j<NODE; j++)
cout<<setw(3) << cost[i][j];
cout<<endl;
}
}
int main(){
floydWarshal();
}

44
Output

3.3Johnson’s algorithm for sparse graphs

3.3.1 What is Johnson’s algorithm?

Johnson's algorithm is a way to find the shortest paths between all pairs of vertices in an edge-
weighted directed graph.

It allows some of the edge weights to be negative numbers, but no negative-weight cycles may
exist. It works by using the Bellman–Ford algorithm to compute a transformation of the input
graph that removes all negative weights, allowing Dijkstra's algorithm to be used on the
transformed graph.

Algorithm for the Johnson:

Let the given graph be G. A new vertex v should be added to the graph, Later add edges from a
new vertex to all vertices of graph G. The modified graph be G.

Use the bellman-ford algorithm on G with v as a source point. The distances calculated by
Bellman-Ford be h[0], h[1],..h[V-1]. Return it if you found a negative weighted cycle. Make a
note that the negative weight cycle cannot be created by new vertex v as there is no edge to v.
All edges are from v.

45
Reweights the edges of the original graph. For each edge (x, y), assign the new weight as
“original weight + h[x] – h[y].”

Code for Johnson’s Algorithm

#include<iostream>
#define INF 9999
using namespace std;
int min(int a, int b);
int cost[10][10], adj[10][10];
inline int min(int a, int b){
return(a<b)?a:b;
}
main() {
intvert,edge,i,j,k,c;
cout<< "Enter no of vertices: ";
cin>>vert;
cout<< "Enter no of edges: ";
cin>> edge;
cout<< "Enter the EDGE Costs:\n";
for(k = 1; k <= edge; k++){
cin>>i>>j>>c;
adj[i][j]=cost[i][j]=c;
}
for(i = 1; i<= vert; i++)
for(j = 1; j <= vert; j++) {
if(adj[i][j] == 0 && i != j)
adj[i][j] = INF;
}
for (k = 1; k <= vert; k++)
for (i = 1; i<= vert; i++)
for (j = 1; j <= vert; j++)
adj[i][j] = min(adj[i][j], adj[i][k] + adj[k][j]);
cout<< "Resultant adj matrix\n";
for (i = 1; i<= vert; i++) {
for (j = 1; j <= vert; j++) {
if (adj[i][j]!=INF)
cout<<adj[i][j]<< " ";
}
cout<< "\n";
}
}

46
Output

47

You might also like