Assignment2 Last
Assignment2 Last
Institute Of Technology
Department Of Computer Science
2014 E.C MSc 1stYear Regular Program
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).
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.
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
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.
Weighted tree
3
The possible spanning trees from the above graph are:
4
The minimum spanning tree from the above spanning tree is
The minimum spanning tree from a graph is found using the following algorithms:
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
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.
5
Example of Kruskal's algorithm
Choose the edge with the least weight, if there are more than 1, choose anyone
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
7
Kruskal's Algorithm Code
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
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
}
}
}
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
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
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:
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.
#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
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.
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
19
int E = graph->E;
intdist[V];
printArr(dist, V);
return;
}
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);
21
BellmanFord(graph, 0);
return 0;
}
Output
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;
class AdjListNode
{
int v;
int weight;
public:
AdjListNode(int _v, int _w) { v = _v; weight = _w;}
intgetV() { return v; }
intgetWeight() { return weight; }
};
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
}
26
dist[s] = 0;
int s = 1;
cout<< "Following are shortest distances from source " << s <<" n";
g.shortestPath(s);
return 0;
}
27
Output
Before preceding the step by step process for implementing the algorithm, let us consider some
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
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
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).
#include <iostream>
using namespace std;
#include <limits.h>
// 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[])
{
32
for (int v = 0; v < V; v++)
if (sptSet[v] == false &&dist[v] <= min)
min = dist[v], min_index = v;
return min_index;
}
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];
}
dijkstra(graph, 0);
return 0;
}
Output
34
3. 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=∞
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.
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.
Initial Graph
Follow the steps below to find the shortest path between all the pairs 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.
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
39
The above algorithm show that
n = no of vertices
for k = 1 to n
for i = 1 to n
for j = 1 to n
40
matrix[i][j] = matrix[i][k] + matrix[k][j];
}
}
}
printMatrix(matrix);
}
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
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.
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
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
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.
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].”
#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