You are on page 1of 51

DEPARTMENT OF INFORMATION TECHNOLOGY

Practical File

B.Tech (IT) 2nd Year –4thSemester

Subject: Design & Analysis of Algorithms Lab


BTIT 406-18

CHANDIGARH ENGINEERING

COLLEGE (LANDRAN)

Faculty Submitted by Dr. Amanpreet Kaur Name: - Hritik Sharma


Associate Professor-IT Roll no.: - 1902629
Department of Information Technology

INDEX
Sr No. Title Date Page No.
1. Code and analysis of Linear Search 10-02-2021 3-8
and Binary Search

2. Code and analyze to sort an array 17-02-2021 9-13


of integers using Merge Sort

3. Code and analyze Pattern matching 24-02-2021 14-17


and Selection Sort algorithm

4. Code and analyze Quick Sort Algorithm 03-03-2021 18-22

5 Code and analyze Knapsack 17-03-2021 23- 24


problem (Dynamic Programming)

6 Code and analysis to do a depth first 31-03-2021 25 - 27


search DFS (Depth First Search) on
an undirected graph

7 Implementation and analysis of 07-04-2021 28 - 31


BFS (Breadth First Search)

8 Code and analyze to find shortest paths 05-05-2021 32 - 38


in a graph with positive edge weights
using Dijkstra’s algorithm

9 Code and analyze to find shortest paths 12-05-2021 39 - 44


in a graph with arbitrary edge weights
using Floyd Warshall’s Algorithm

10 Code and analyze to find the 19-05-2021 44-51


minimum spanning tree in a
weighted, undirected graph using
Prims’ algorithm.

2
Hritik Sharma
1902629
Department of Information Technology

Experiment No.-1
Title: Code and analysis of Linear Search and Binary Search Objective: 1.
To write a program in C++ to search the desired element from the list using the linear search
2. To do the analysis of the Linear Search Algorithm
Description of Algorithm: Let ‘A’ be a linear array with n elements. The following
program searches for a given item ’x’ in ‘A’ by comparing ‘x’ with each element in the array
’A’.
Linear Search (Array A, Value x)
Step 1: Set i to 1
Step 2: if i>n then go to step 7
Step3: if A[i]==x then go to step 6
Step 4: Set i to i+1
Step 5: Go to Step 2
Step 6: Print Element x found at index i and go to step 8
Step 7: Print element not found
Step 8: Exit
Pseudocode
Procedure linear_search(list,value)
For each item in the list
if match item == value
return the item’s location
end if
end for
end procedure
Code:
#include<iostream>
using namespace std;
int main()
{
int hritik[40],n,i,ele;
cout<<"Enter the no of element you want to enter"<<endl;

3
Hritik Sharma
1902629
Department of Information Technology

cin>>n;
cout<<"Enter the elements"<<endl;
for(i=0;i<n;i++)
{
cin>>hritik[i];
}
cout<<"Enter the element you want to find"<<endl;
cin>>ele;
for(i=0;i<n;i++)
{
if(hritik[i]==ele)
{
cout<<"Element" <<ele <<"is found at " <<i+1 <<"position"<<endl;
cout<<"Roll no is 1902629"<<endl;
break;
}
}
if(i>=n)
{
cout<<"Element" <<ele <<"is not found in the list"<<endl;
cout<<"Roll no is 1902629"<<endl;
}
return 0;
}

4
Hritik Sharma
1902629
Department of Information Technology

Output:
Analysis of Linear Search
The complexity of the above program is measured by the number of comparisons f(n)
required to find ‘x’ in ‘A’ where ‘A’ contains n items
Worst Case occurs when one has to search through entire array ‘A’ i.e. item does not
appear in ‘A’. Thus algorithm requires f(n)=n+1 comparisons
Average Case running time is measured using probabilistic notation of expectation and is
found to be f(n)=(n+1)/2
Thus the average number of comparisons required to find the location of ‘x’ is approximately
equal to the half number of elements in the array
Best Case occurs when we found the element at the first comparison in the array ‘A’. Thus
algorithm requires f(n)=1 comparison.

5
Hritik Sharma
1902629
Department of Information Technology
Objective: 1. To write a program in C++ to search the desired element from the list using
Binary Search
2. To do analysis of Binary Search Algorithm
Description of Algorithm: Binary Search is a fast search algorithm. This search
algorithm works on the principle of divide and conquer. For this algorithm to work properly
the data collection should be in the sorted form.
Binary search looks for a particular item by comparing the middle most item of the collection.
If match occurs then the index of item is returned. If the middle is greater than the item, then
the item is searched in the sub-array to the left of the middle item. Otherwise the is searched
for in the sub-array to the right of the middle term. This process continues on the sub-array as
well until the size of the subarray reduces to zero.
Binary_Search(A,lower_bound,upper_bound,val)
Step 1: [initialize] Set beg=lower_bound
end=upper_bound,pos=-1
Step 2:Repeat Steps 3 and 4 while beg<=end
Step 3:Set mid=(beg+end)/2
Step 4: if A[mid]=val
Set pos=mid
Print pos
Go to step 6
Else if A[mid]>val
Set end=mid-1
Else
Set beg=mid+1
[end of if]

6
Hritik Sharma
1902629
Department of Information Technology

[end of loop]
Step 5: if pos=-1
Print”value is not present in the array”
[end of if]
Step 6: exit
Pseudocode
Function binary_search(A,n,T)
L=0, R=n-1
While L<=R do
M=floor((L+R)/2)
If A[m] < T then
L=m+1
Else if A[m] >T then
R=m-1
Else return m
Return unsuccessful
Code:
#include<iostream>
using namespace std;
int main()
{
int hritik[50],n,ele,i,first,last,mid;
cout<<"Enter the no of elements you want to enter"<<endl;
cin>>n;
cout<<"Enter the elements in ascending oeder"<<endl;
for(i=0;i<n;i++)
{
cin>>hritik[i];
}
cout<<"Enter the element you want to find"<<endl;
cin>>ele;
first=0;
last=n-1;

7
Hritik Sharma
1902629
Department of Information Technology

while(first<=last)
{
mid=(first+last)/2;
if(hritik[mid]==ele)
{
cout<<ele << "is found at" <<mid+1 << "position"<<endl;
cout<<"Roll No is 1902629"<<endl;
break;
}
else if(hritik[mid]>ele)
last=mid-1;
else
first=mid+1;
}
if(first>last)
cout<<ele << "is not found in the list"<<endl;
return 0;
}

8
Hritik Sharma
1902629
Department of Information Technology

Output
Analysis-Binary Search
• In the base case, the algorithm will end up either finding the element or just failing and
returning false. In both cases, the algorithm is going to take a constant time because
only comparisons and return statements are going to be executed.
• Otherwise, comparisons and calculations of the middle element will take constant time
and then the problem is divided into another problem of size n2
• Let T(n) be the number of comparisons in worst-case in an array of n element. Hence •
T(n)= {0 if n=1,T(n/2)+1 otherwise
• Worst case O(log n)
• Best case O(1)
• Average case O(log n)
• Worst case space complexity O(1)

9
Hritik Sharma
1902629
Department of Information Technology

Experiment 2
• Title: Code and analyse to sort an array of integers using Merge Sort •
Objectives: 1. To write a program in C++ for Merge Sort
2. To do the analysis of the Algorithm implemented
• Description of Algorithm: Merge Sort is a Divide and Conquer algorithm. Merge
sort keeps on dividing the list into equal halves until it can no more be divided. By
definition, if it is only one element in the list, it is sorted. Then, merge sort combines
the smaller sorted lists keeping the new list sorted too. Merge sort works with
recursion.
• Algorithm:
Step 1: if it only one element in the list it is already sorted, return.
Step 2: divide the list recursively int two halves until it can no more be
divided. Step 3: merge the smaller lists into two new list in sorted order.
• Pseudocode:
Procedure mergesort(var a as array)
if(n==1)
return a
var l1 as array =a[0]…..a[n/2]
var l2 as array=a[n/2+1]….a[n]
l1=mergesort(l1)
l2=mergesort(l2)
return merge(l1,l2)
end procedure
• Code:

#include<iostream>
using namespace std;
void mergesort(int a[30],int lb,int ub);
void merge(int a[30], int lb,int ub);
int main()
{
int a[30],n,i;
cout<<"Enter the no of digits";
cin>>n;
10
Hritik Sharma
1902629
Department of Information Technology

cout<<"enter the digits";


for(i=0;i<n;i++)
{
cin>>a[i];
}
mergesort(a,0,n-1);
cout<<"Roll No is
1902629"<<endl; cout<<"\n sorted
array";
for(i=0;i<n;i++)
{
cout<<a[i]<<endl;
}
return 0;
}
void mergesort(int a[],int lb, int ub)
{
int mid;
if(lb<ub)
{
mid=(lb+ub)/2;
mergesort(a,lb,mid);
mergesort(a,mid+1,ub);
merge(a,lb,ub);
}
}
void merge(int a[30],int lb,int ub)
{
int start,end,l,k,b[30],mid;
start=lb;
mid=(lb+ub)/2;
k=mid+1;
l=lb;
while (lb<=mid && k<=ub)
{
11
Hritik Sharma
1902629
Department of Information Technology

if(a[lb]>=a[k])
{
b[l]=a[k];
k=k+1;
}
else
{
b[l]=a[lb];
lb=lb+1;
}
l=l+1;
}
if(lb>mid)
{
while (k<=ub)
{
b[l]=a[k];
l=l+1;
k=k+1;
}
}
else
while
(lb<=mid) {
b[l]=a[lb];
l=l+1;
lb=lb+1;
}
for(l=start;l<=ub;l+
+) {
a[l] = b[l];
}
}

12
Hritik Sharma
1902629
Department of Information Technology

• Output:
Analysis of Merge Sort
• Divide Step- The divide step takes constant time, regardless of the subarray size. After
all, divide step just computes the midpoint ‘q’ of the indices ‘p’ and ‘r’. It takes
constant time O(1)
• Conquer step- In this, we recursively sort two subarrays of approximately n/2 elements
each, takes some amount of time, but we’ll account for that time when we consider the
subproblems.
• The combine step merges a total of n elements, O(n).
• The divide and combines steps together take O(n) time.
Merging Time

13
Hritik Sharma
1902629
Department of Information Technology
• •

The total time for mergeSort is the sum of the merging times for all the level. If there are ‘l’
levels in the tree, then the total merging time is l.cn.
• There are ‘log n’ levels in division steps as Merge sort follows. The binary-search
algorithm takes log(n) time, because of the fact that height of the tree is log n • The total
numbers of nodes, n, in the tree is equal to the sum of the nodes on all the level :
1+21+22+23+….+2h-1=n From CS 201 we know that:1+21+22+23+…+2h 1=2h-1.
Therefore: 2h-1=n 2h =n+1 log2 2h=log2(n+1)=log2(n+1) Therefore h is O(log n)

14
Hritik Sharma
1902629
Department of Information Technology

Experiment No.- 3
• Title- Code and analyze Pattern matching and Selection Sort algorithms • Objective-
1. To write program in C++ for finding the occurrences of a pattern P in a given sting T.
2.To write a program in C++ for selection sort algorithm.
3.To do the analysis of the Algorithms implemented.
• Theory:
Brute Force Pattern Matching:
The brute-force pattern matching algorithm compares the pattern P with the text T for
each possible shift of P relative to T, until either
A match is found
All the placements of the pattern have been tried
Algorithm Brute Force Match(T,P):
Searching for a pattern, P[0…m-1], in text T[0…,n-1]
Algorithm BFStringMatch(T[0….n-1],P[0…m-1])
For i🡨0 to n-m do
j🡨0
while j<m and P[j]=T[i+j] do
j++
if j=m then return
else break while loop
return -1
• Code:
#include<iostream>
#include<string.h>
using namespace std;
void search(char* P, char* T)
{
int M = strlen(P);
int N = strlen(T);
for (int i = 0; i <= N - M; i++) {
int j;

15
Hritik Sharma
1902629
Department of Information Technology

for (j = 0; j < M; j++)


if (T[i + j] != P[j])
break;
if (j == M)
cout << "Pattern found at index "
<< i << endl;
}
}
int main()
{
char T[] = "bbacdcbcddcdaddaaabcbcb";
char P[] = "abc";
search(P, T);
cout<<"Roll No is 1902629"<<endl;
return 0;
}
• Output:

• Analyse of Pattern Matching :


Brute-Force pattern matching runs in time O(NM) since the total number of
comaprisons are M(N-M+1)
Also, the worst case time complexity: O(MN)
• Brute Force Selection Sorting :

16
Hritik Sharma
1902629
Department of Information Technology

Selection sort is an in-place comparisons sorting algorithm that uses brute force to sort
an array. It uses a small constant amount of space for extra storage. The algorithm
divides the array into two subarrays:
A sorted subarray
An unsorted subarray
The sorted subarray is empty in the beginning. In every iteration, the smallest element
of the unsorted array will be appended to the end of the sorted array by swapping. This
way, the sorted array will eventually contain all the elements of the original array. •
Algorithm:
SelectionSort(A[0….n-1])
For i🡨0 to n-2 do
Min🡨 i
For j🡨 i+1 to n-1 do
If A[j]<a[min] then min🡨 j
Swap A[i] and A[min]
• Code:
#include<iostream>
using namespace std;
int main()
{
int a[]={7,0,12,9,44},n,i,j,temp,b;
n=sizeof(a)/sizeof(int);
cout<<"Size of array is"<<n<<endl;
cout<<"Unsorted array is"<<endl;
for(i=0;i<n;i++)
cout<<a[i]<<endl;
for(i=0;i<n-1;i++)
{
temp=i;
for(j=i+1;j<n;j++)
{
if(a[temp]>a[j])
temp=j;

17
Hritik Sharma
1902629
Department of Information Technology

}
if(i!=temp)
{
b=a[temp];
a[temp]=a[i];
a[i]=b;
}
}
cout<<"Sorted array is"<<endl;
for(i=0;i<n;i++)
cout<<a[i]<<endl;
cout<<"Roll No is 1902629"<<endl;
return 0;
}

• Output:

• Selection Sort Analysis:


Problem size is n, array length
Basic operation is “Comparison in if test”
Best Case=Worst Case Complexity
The count C(n)=∑n-2 i=0 ∑n-1 j=i+1 1
18
Hritik Sharma
1902629
Department of Information Technology

Solve C(n) =∑n-2 i=0[(n-1)-(i+1)+1]=∑n-2 i=0[n-1-i]


C(n)=(n-2-0)*(n-1-i)= ∅(n2)

Experiment No 4
• Title: Divide and Conqure- Code and analyze Quick Sort Algorithm •
Objective: 1. To write program in C++ to sort the integers using Quicksort 2.
To do the analysis of the Algorithms implemented
• Theory:
It is an algorithm of Divide and Conquer type
Divide: Rearrange the elements and split arrays into two sub-arrays and an element in
between search that each element in left sub array is less than or equal to the average
element and each element in the right sub-array is larger than the middle element.
Conquer: Recursively, sort two sub arrays
Combine: Combine the already sorted array
• Pseudocode:
Quicksort(array,start,end)
{
If(start<end)
{
Pindex=partition(arr,start,end);
quicksort(arr,start,pindex-1);
quicksort(arr, pindex+1,end);
}
}
Partition
Partition(arr,start,end)
pindex=start;
pivot=arr[end];
for(arr[i]<pivot)
{
swap arr[i] and arr[pindex]

19
Hritik Sharma
1902629
Department of Information Technology

increment pindex by1


}
Finally, swap(arr[end],arr[pindex])
return pindex
}
• Algorithm:
Quicksort(array,start,end)
{
if(start<end)
{
pindex=partition(arr,start,end)
quicksort(arr,start,pindex-1);
quicksort(arr, pindex+1,end);
}
}
Partition:
An array => arr[size]
Starting index=>start
Ending index=>end
Initialization
Set i=start and pindex =start
i is used to iterate the array elements
pindex is used to mark the final position of the pivot
And pick arr[end] as the pivot , pivot=arr[end] •
Code:
#include<iostream>
using namespace std;
int quicksort(int a[30],int lb,int ub);
int partition(int a[30],int lb,int ub);
int loc,n,i,a[30],lb,ub,start,en;
int main()
{
cout<<"enter no the digits";

20
Hritik Sharma
1902629
Department of Information Technology

cin>>n;
cout<<"enter the digits";
for(i=0;i<n;i++)
{
cin>>a[i];
}
quicksort(a,0,n-1);
cout<<"Roll no is 1902629"<<endl;
cout<<"sorted order is";
for(i=0;i<n;i++)
{
cout<<a[i]<<endl;
}
return 0;
}
int quicksort(int a[30],int lb,int ub)
{
if(lb<ub)
{
loc=partition(a,lb,ub);
quicksort(a,lb,loc-1);
quicksort(a,loc+1,ub);
}
return 0;

}
int partition(int a[30],int lb,int ub)
{
int pivot,temp;
pivot=a[lb];
start=lb;
en=ub;
while (start<en)
{
21
Hritik Sharma
1902629
Department of Information Technology

while(a[start]<=pivot &&
start<en) {
start=start+1;
}
while (a[en]>pivot)
{
en=en-1;
}
if(start<en)
{
temp=a[start];
a[start]=a[en];
a[en]=temp;
}
}
a[lb]=a[en];
a[en]=pivot;
return en;
}

22
Hritik Sharma
1902629
Department of Information Technology

Output:
• Analysis of Quick Sort:
Worst Case Complexity(Big-O): O(n2)
It occurs when the pivot element picked is either the greatest or the smallest element
This condition leads to the case in which the pivot element lies in an extreme and of
the sorted array. One sub-array is 1 elements. Thus, quicksort is called only on this
sub array. However the quick sort algorithm has better performance for scattered
pivots Best Case Complexity: O(n*logn)
It occurs when the pivot element is always the middle element or near to the middle
element.
Average Case Complexity: O(n*logn)
It occurs when the above conditions do not occur
Solving time complexity:
T(n)=2T(n/2)+partition(n)
T(n)= 2T(n/2)+n ----------(1)
Put n=n/2
T(n/2)= 2T(n/22)+n/2 --------(2)

23
Hritik Sharma
1902629
Department of Information Technology

Put (2) in (1)


T(n)= 2[2T(n/22)+n/2]+n
T(n)= 22 T(n/22)+2n-------(3)
Put n=n/22 in equation (1)
T(n/22)= 2T(n/23)+n/22--------(4)
Put (4) in (3)
T(n)= 22[2T(n/23)+n/22]+2n
In general
T(n)= 2i T(n/2i)+in-----(5)
where i is natural number
stopping condition is n/2i=1
n=2i ,i=log2n , T(1)=0 -------(6)
put (6) in (5)
T(n)=nT(1)+nlogn
T(n)=n*logn

Experiment No: 5

Title: Code and analyze Knapsack problem (Dynamic Programming)


Objectives:
1) Implement 0/1 Knapsack Problem using Dynamic Programming

2) To do the analysis of the Algorithms implemented

THEORY:
The knapsack problem is a problem in combinatorial optimization: Given a set of items, each with a weight
and a value, determine the number of each item to include in a collection so that the total weight is less
than or equal to a given limit and the total value is as large as possible.

Algorithm:
Dynamic-0-1-knapsack (v, w, n, W)

for w = 0 to W do //W capacity of KS, wi the weight of current item

c[0, w] = 0

for i = 1 to n do

24
Hritik Sharma
1902629
Department of Information Technology

c[i, 0] = 0

for w = 1 to W do

if wi ≤ w then //w is the remaining


capacity of KS if vi + c[i-1, w-wi]

then

c[i, w] = vi + c[i-1, w-wi]

else c[i, w] = c[i-1, w]

else

c[i, w] = c[i-1, w]

Code:
#include <iostream>
#include <climits>
using namespace std;
int knapSack(int v[], int w[], int n, int W) {
if (W < 0)
return INT_MIN;
if (n < 0 || W == 0)
return 0;
int in = v[n] + knapSack(v, w, n - 1, W - w[n]);
int ex = knapSack(v, w, n - 1, W);
return max (in, ex);
}
int main() {
cout<<" Hritik Sharma"<<endl;
cout<<"1902629"<<endl;
int v[] = { 10, 20, 30, 40, 60, 70 };
int w[] = { 1, 2, 3, 6, 7, 4 };
int W = 7;
int n = sizeof(v) / sizeof(v[0]);
cout << "Knapsack value is " << knapSack(v, w, n - 1, W);
return 0;
}

OUTPUT:

25
Hritik Sharma
1902629
Department of Information Technology
Time Complexity-

● Each entry of the table requires constant time θ(1) for its computation.
● It takes θ(nw) time to fill (n+1)(w+1) table entries.
● It takes θ(n) time for tracing the solution since the tracing process traces the n rows. ●
Thus, overall θ(nw) time is taken to solve the 0/1 knapsack problem using dynamic
programming.

Experiment No: 6

Title: Code and analysis to do a depth first search DFS (Depth First Search) on an undirected
graph

Objectives:

1) Implementing an application of DFS such as (i) to find the topological sort of a directed
acyclic gaph.

2) To do the analysis of the Algorithms implemented

THEORY:

26
Hritik Sharma
1902629
Department of Information Technology

Depth First Search algorithm(DFS) traverses a graph in a depthward motion and uses a
stack to remember to get the next vertex to start a search when a dead end occurs in
any iteration

Algorithm:

Rule 1 − Visit adjacent unvisited vertex. Mark it as visited. Display it. Push
it in a stack.

Rule 2 − If no adjacent vertex is found, pop up a vertex from the


stack. (It will pop up all the vertices from the stack which do not
have adjacent vertices.)

Rule 3 − Repeat Rule 1 and Rule 2 until stack is Empty.


Code:
#include <iostream.h>
using namespace std;

class Graph {

// Number of vertex
int v;

// Number of edges
int e;

// Adjacency matrix
int** adj;

27
Hritik Sharma
1902629
Department of Information Technology
public:
// To create the initial adjacency matrix
Graph(int v, int e);

// Function to insert a new edge


void addEdge(int start, int e);

// Function to display the DFS traversal


void DFS(int start, vector<bool>& visited);
};

// Function to fill the empty adjacency matrix


Graph::Graph(int v, int e)
{
this->v = v;
this->e = e;
adj = new int*[v];
for (int row = 0; row < v; row++) {
adj[row] = new int[v];
for (int column = 0; column < v; column++) {
adj[row][column] = 0;
}
}
}

// Function to add an edge to the graph


void Graph::addEdge(int start, int e)
{

// Considering a bidirectional edge


adj[start][e] = 1;
adj[e][start] = 1;
}

// Function to perform DFS on the graph


void Graph::DFS(int start, vector<bool>&
visited) {

// Print the current node


cout << start << " ";

// Set current node as visited


visited[start] = true;

// For every node of the graph


for (int i = 0; i < v; i++) {

// If some node is adjacent to the current node


// and it has not already been visited

28
Hritik Sharma
1902629
Department of Information Technology

if (adj[start][i] == 1 && (!visited[i])) {


DFS(i, visited);
}
}
}

int main()
{
int v = 5, e = 4;
cout<<"Hritik Sharma"<<endl;
cout<<"1902629"<<endl;
// Create the graph
Graph G(v, e);
G.addEdge(0, 1);
G.addEdge(0, 2);
G.addEdge(0, 3);
G.addEdge(0, 4);

vector<bool> visited(v, false);

G.DFS(0, visited);
}

29
Hritik Sharma
1902629
Department of Information Technology
OUTPUT:

Time Complexity

The time complexity of DFS if the entire tree is traversed is O(V) where V is the number of
nodes
For an undirected graph, each edge appears twice. Once in the adjacency list of either end of
the edge. The time complexity for this case will be O(V) + O (2E) ~ O(V + E).
Experiment No: 7

TITLE: Implementation and analysis of BFS (Breadth First Search)


OBJECTIVES:
1) Implement BFS
2) To do the analysis of the Algorithms implemented

THEORY:

30
Hritik Sharma
1902629
Department of Information Technology

Breadth First Search algorithm(BFS) traverses a graph in a breadthwards motion and uses a
queue to remember to get the next vertex to start a search when a dead end occurs in any
iteration.
Algorithm:

Rule 1 − Visit adjacent unvisited vertex. Mark it visited.

Display it. Insert it in a queue. Rule 2 − If no adjacent vertex

is found, remove the first vertex from the queue. Rule 3 −

Repeat Rule 1 and Rule 2 until the queue is empty.

CODE:
#include <iostream>

#include <bits/stdc++.h>

using namespace std;

vector<bool> v;

vector<vector<int>> g;

void bfsTraversal(int b)

//Declare a queue to store all the nodes connected to b

queue<int> q;

//Insert b to queue

q.push(b);

31
Hritik Sharma
1902629
Department of Information Technology

//mark b as visited

v[b] = true;

cout << "\n\nThe BFS Traversal is: ";


while (!q.empty())

int a = q.front();

q.pop(); //delete the first element from queue for

(auto j = g[a].begin(); j != g[a].end(); j++) {

if (!v[*j])

v[*j] = true;

q.push(*j);

cout << a << " ";

void makeEdge(int a, int b)

g[a].push_back(b); //an edge from a to b (directed graph) }

int main()

cout<<"Hritik Sharma"<<endl;

cout<<"1902629"<<endl;

int n, e;

32
Hritik Sharma
1902629
Department of Information Technology

cout << "Enter the number of vertices: ";

cin >> n;

cout << "\n\nEnter the number of edges: ";

cin >> e;

v.assign(n, false);
g.assign(n, vector<int>());

int a, b, i;

cout << "Enter the edges with source and target vertex: \n ";

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

cin >> a >> b;

makeEdge(a, b);

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

//if the node i is unvisited

if (!v[i])

bfsTraversal(i);

cout << "\n\n\n";

return 0;

33
Hritik Sharma
1902629
Department of Information Technology

OUTPUT:
Time Complexity:
If V is the number of vertices and E is the number of edges of a graph, then the time
complexity for BFS can be expressed as O (|V|+|E|). Having said this, it also depends on the
data structure that we use to represent the graph. If we use the adjacency list (like in our
implementation), then the time complexity is O(|V|+|E|).

If we use the adjacency matrix, then the time complexity is O (V^2).

Experiment No: 8

TITLE: Code and analyze to find shortest paths in a graph with positive edge weights using
Dijkstra’s algorithm.

OBJECTIVES:

34
Hritik Sharma
1902629
Department of Information Technology

Code and analyze to find shortest paths in a graph with positive edge weights using Dijkstra’s
algorithm.

THEORY:

Dijkstra’s algorithm, published in 1959 and named after its creator Dutch computer scientist
Edsger Dijkstra, can be applied on a weighted graph. The graph can either be directed or
undirected.

This is a single-source shortest path algorithm and aims to find solution to the given problem
statement This algorithm works for both directed and undirected graphs It works only for
connected graphs The graph should not contain negative edge weights
The algorithm predominantly follows the Greedy approach for finding locally optimal
solution. But, it also uses Dynamic Programming approach for building globally optimal
solution, since the previous solutions are stored and further added to get final distances from
the source vertex The main logic of this algorithm is based on the following formula-
dist[r]=min(dist[r], dist[q]+cost[q][r])

DIJKSTRA’s ALGORITHM -

Input Data

Cost Adjacency Matrix for Graph G, say cost

Source vertex, say s

Output Data

Spanning tree having shortest path from s to all other vertices in G

Step 1; Set dist[s]=0, S=ϕ // s is the source vertex and S is a 1-D array having all the visited
vertices

Step 2: For all nodes v except s, set dist[v]= ∞

Step 3: find q not in S such that dist[q] is minimum // vertex q should not be

visited Step 4: add q to S // add vertex q to S since it has now been visited

Step 5: update dist[r] for all r adjacent to q such that r is not in S //vertex r should not be

visited dist[r]=min(dist[r], dist[q]+cost[q][r]) //Greedy and Dynamic approach

Step 6: Repeat Steps 3 to 5 until all the nodes are in S // repeat till all the vertices have

been visited

Step 7: Print array dist having shortest path from the source vertex u to all other vertices

35
Hritik Sharma
1902629
Department of Information Technology

Step 8: Exit

Code:

#include<iostream>

using namespace std;

#define V 5 //Defines total number of vertices in the graph

#define INFINITY 999


int min_Dist(int dist[], bool visited[])

//This method used to find the vertex with minimum distance and is not yet visited

int min=INFINITY, index; //Initialize min with infinity for(int

v=1;v<=V;v++)

if(visited[v]==false &&dist[v]<=min)

min=dist[v];

index=v;

return index;

void Dijkstra(int cost[V][V],int src) //Method to implement shortest path algorithm

int dist[V];

bool visited[V];

for(int i=1;i<=V;i++) //Initialize dist[] and visited[] {

36
Hritik Sharma
1902629
Department of Information Technology

dist[i]=INFINITY;

visited[i]=false;

//Initialize distance of the source vertex to zero

dist[src]=0;

for(int c=2;c<=V;c++)

//u is the vertex that is not yet included in visited and is having minimum
distance
int u=min_Dist(dist,visited);

visited[u]=true; //vertex u is now visited

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

//Update dist[v] for vertex v which is not yet included in visited[] and

//there is a path from src to v through u that has smaller distance than

// current value of dist[v]

if(!visited[v] && cost[u][v] &&dist[u]+cost[u][v]<dist[v])

dist[v]=dist[u]+cost[u][v];

//will print the vertex with their distance from the source

cout<<"The shortest path "<<src<<" to all the other vertices is: \n";

for(int i=1;i<=V;i++)

if(i!=src)

cout<<"source:"<<src<<"\t destination:"<<i<<"\t MinCost

is:"<<dist[i]<<"\n"; }

37
Hritik Sharma
1902629
Department of Information Technology

int main()

int cost[V][V], i,j, s;

cout<<"Hritik Sharma"<<endl;

cout<<"1902629"<<endl;

cout<<"\n Enter the cost matrix weights";

for(i=1;i<=V;i++) //Indexing ranges from 1 to n

for(j=1;j<=V;j++)
{

cin>>cost[i][j];

//Absence of edge between vertices i and j is represented by INFINITY

if(cost[i][j]==0)

cost[i][j]=INFINITY;

cout<<"\n Enter the Source Vertex";

cin>>s;

Dijkstra(cost,s);

return 0; }

38
Hritik Sharma
1902629
Department of Information Technology

OUTPUT:
ANALYSIS OF DIJKSTRA’s ALGORITHM:

O(V) time since we initially add every vertex in the graph to the priority queue. Once the queue is
constructed the while loop is executed once for every vertex since vertices are all added at the
beginning and only removed after that. Within that loop each call to delMin, takes

O(logV)

O(log⁡V) time. Taken together that part of the loop and the calls to delMin take

O(Vlog(V))

O(Vlog⁡(V)). The for loop is executed once for each edge in the graph, and within the for loop
the call to decrease Key takes time O(Elog(V)).

O(Elog⁡(V)). So the combined running time is

O((V+E)log(V)).

39
Hritik Sharma
1902629
Department of Information Technology

Experiment No. 9

TITLE: Code and analyze to find shortest paths in a graph with arbitrary edge weights using
Floyd Warshall’s Algorithm

OBJECTIVES:
Code and analyze to All pair shortest path of directed graph using Floyd Warshall’s

Algorithm THEORY:

The Floyd Warshall Algorithm is for solving the All Pairs Shortest Path problem. The
problem is to find shortest distances between every pair of vertices in a given edge weighted
directed Graph.

Floyd-Warshall Algorithm is an algorithm for finding the shortest path between all the pairs
of vertices in a weighted graph. This algorithm works for both the directed and undirected
weighted graphs. But, it does not work for the graphs with negative cycles (where the sum of
the edges in a cycle is negative).

FLOYD WARSHALL’s ALGORITHM :

let dist be a |V| × |V| array of minimum distances

initialized to ∞ (infinity)

for each edge (u, v) do

dist[u][v+ ← w(u, v)

// The weight of the edge (u, v)

for each vertex v do

dist[v][v+ ← 0

for k from 1 to |V|

for i from 1 to |V|

for j from 1 to |V|

if dist[i][j] > dist[i][k] + dist[k][j]

dist[i][j+ ← dist*i][k] + dist[k][j]

end if

Code:

// C Program for Floyd Warshall Algorithm

40
Hritik Sharma
1902629
Department of Information Technology

#include<stdio.h>

// Number of vertices in the graph

#define V 4
/* Define Infinite as a large enough value. This value will be used

for vertices not connected to each other */

#define INF 99999

// A function to print the solution matrix

void printSolution(int dist[][V]);

// Solves the all-pairs shortest path problem using Floyd Warshall algorithm

void floydWarshall (int graph[][V])

/* dist[][] will be the output matrix that will finally have the shortest distances between every
pair of vertices */

int dist[V][V], i, j, k;

/* Initialize the solution matrix same as input graph matrix. Or we can say the initial values
of shortest distances are based on shortest paths considering no intermediate vertex. */

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

for (j = 0; j < V; j++)

dist[i][j] = graph[i][j];

/* Add all vertices one by one to the set of intermediate vertices.

---> Before start of a iteration, we have shortest distances between all

pairs of vertices such that the shortest distances consider only the

vertices in set {0, 1, 2, .. k-1} as intermediate vertices.

41
Hritik Sharma
1902629
Department of Information Technology

----> After the end of a iteration, vertex no. k is added to the set of

intermediate vertices and the set becomes {0, 1, 2, .. k} */

for (k = 0; k < V; k++)

// Pick all vertices as source one by one


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

// Pick all vertices as destination for the above picked source

for (j = 0; j < V; j++)

// If vertex k is on the shortest path from i to j, then update the value of dist[i][j] if

(dist[i][k] + dist[k][j] < dist[i][j])

dist[i][j] = dist[i][k] + dist[k][j];

// Print the shortest distance matrix

printSolution(dist);

void printSolution(int dist[][V])

printf ("Following matrix shows the shortest distances between every pair of vertices \n");

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

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

42
Hritik Sharma
1902629
Department of Information Technology

if (dist[i][j] == INF)

printf("%7s", "INF"); else

printf ("%7d", dist[i][j]); }

printf("\n");
}

// driver program to test above function

int main()

int graph[V][V] = { {0, 3, INF, 5},

{2, 0, INF, 4}, {INF, 1, 0, INF},

{INF, INF, 2, 0} };

// Print the solution

floydWarshall(graph);

printf("\n");

printf("Hritik Sharma \n");

printf("1902629 \n");

43
Hritik Sharma
1902629
Department of Information Technology

return 0;

OUTPUT:
Time Complexity-

● The Floyd Warshall Algorithm consists of three loops over all the nodes. ● The

inner most loop consists of only constant complexity operations. ● Hence, the

asymptotic complexity of the Floyd Warshall algorithm is O(n3). ● Here, n is the

number of nodes in the given graph.

Experiment No. 10

TITLE: Code and analyze to find the minimum spanning tree in a weighted, undirected graph
using Prims’ algorithm.

OBJECTIVE:

To study and implement MST using Prim’s Algorithm.

THEORY:

44
Hritik Sharma
1902629
Department of Information Technology

A minimum spanning tree (MST) or minimum weight spanning tree is a subset of the edges of
a connected, edge-weighted undirected graph that connects all the vertices together, without
any cycles and with the minimum possible total edge weight

It is a spanning tree whose sum of edge weights is as small as possible. More generally, any
edge-weighted undirected graph (not necessarily connected) has a minimum spanning forest,
which is a union of the minimum spanning tree of connected components

If the minimum cost edge e of a graph is unique, then this edge is included in any MST.

Proof: if e was not included in the MST, removing any of the (larger cost) edges in the cycle
formed after adding e to the MST, would yield a spanning tree of smaller weight.

PROCEDURE:

Prim’s algorithm is also a Greedy algorithm. It starts with an empty spanning tree. The idea is
to maintain two sets of vertices. The first set contains the vertices already included in the
MST; the other set contains the vertices not yet included. At every step, it considers all the
edges that connect the two sets, and picks the minimum weight edge from these edges. After
picking the edge, it moves the other endpoint of the edge to the set containing MST.

A group of edges that connects two sets of vertices in a graph is called cut in graph theory. So,
at every step of Prim’s algorithm, we find a cut (of two sets, one contains the vertices already
included in MST and other contains rest of the vertices), pick the minimum weight edge from
the cut and include this vertex to MST Set (the set that contains already included vertices).

How does Prim’s Algorithm Work? The idea behind Prim’s algorithm is simple, a spanning
tree means all vertices must be connected. So the two disjoint subsets (discussed above) of
vertices must be connected to make a Spanning Tree. And they must be connected with the
minimum weight edge to make it a Minimum Spanning Tree.

Let us understand with the following example:

The MST Set is initially empty and keys assigned to vertices are {0, INF, INF, INF, INF,
INF,INF, INF} where INF indicates infinite. Now pick the vertex with minimum key value.
The vertex 0 is picked, including it in MST Set. So MST Set becomes {0}. After including
MST Set, update key values of adjacent vertices. Adjacent vertices of 0 are 1 and 7. The key
values of 1 and 7 are updated as 4 and 8. Following subgraph shows vertices and their key
values, only the vertices with finite key values are shown. The vertices included in MST are
shown in green color.

Pick the vertex with minimum key value and not already included in MST (not in mst SET).
The vertex 1 is picked and added to MST Set. So MST Set now becomes {0, 1}. Update the
key values of adjacent vertices of 1. The key value of vertex 2 becomes 8. Pick the vertex with
minimum key value and not already included in MST (not in mst SET). We can either pick
vertex 7 or vertex 2, let vertex 7 is picked. So MST Set now becomes {0, 1, 7}.Update the key
values of adjacent vertices of 7. The key value of vertex 6 and 8 becomes finite(7 and 1
respectively).Pick the vertex with minimum key value and not already included in MST (not
in mst SET).Vertex 6 is picked. So mstSet now becomes {0, 1, 7, 6}. Update the key values of

45
Hritik Sharma
1902629
Department of Information Technology

adjacent vertices of 6. The key value of vertex 5 and 8 are updated.We repeat the above steps
until mst Set includes all vertices of given graph

ALGORITHM:

Prim's Algorithm for implementing minimum cost Spanning tree. E = Set Of Edges in G,

N = No. of Vertices, T = Final Array Matrix, Finally MINCOST is returned.

ALGORITHM(E, COST, N, T)
{

let (K, L) be an edge m cost in E;

mincost:=cost (K, L);

T [1,1]=K; T[1,2]=L;

for i=1 to N do;

if COST [i,L]&lt;COST[i then near[i]=L;

else near [i]:=K;

near [K]=near [L]=0;

for i=2 to N-1 do;

let j be an index such that near [j]!=0 and

cost [j,near[j]] is minimum;

T [i, 1]=j;T[i,2]=near[j];

mincost=mincost+cost [j,near[j])

near [j]: =0;

for K=1 to N do

if ((near [K]! =0and (cost [K,near[K]&gt;cost[K,j])

then near [K]=j;

return mincost;

46
Hritik Sharma
1902629
Department of Information Technology

Code:

#include<iostream>

using namespace std;

// Number of vertices in the graph

const int V=6;


// Function to find the vertex with minimum key value

int min_Key(int key[], bool visited[])

int min = 999, min_index; // 999 represents an Infinite value

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

if (visited[v] == false && key[v] < min) { //

vertex should not be visited

min = key[v];

min_index = v;

return min_index;

// Function to print the final MST stored in parent[]

int print_MST(int parent[], int cost[V][V])

int minCost=0;

cout<<"Edge \tWeight\n";

for (int i = 1; i< V; i++) {

47
Hritik Sharma
1902629
Department of Information Technology

cout<<parent[i]<<" - "<<i<<" \t"<<cost[i][parent[i]]<<" \n";

minCost+=cost[i][parent[i]];

cout<<"Total cost is"<<minCost;

// Function to find the MST using adjacency cost matrix representation


void find_MST(int cost[V][V])

int parent[V], key[V];

bool visited[V];

// Initialize all the arrays

for (int i = 0; i< V; i++) {

key[i] = 999; // 999 represents an Infinite value

visited[i] = false;

parent[i]=-1;

key[0] = 0; // Include first vertex in MST by setting its key vaue to 0.

parent[0] = -1; // First node is always root of MST

// The MST will have maximum V-1 vertices

for (int x = 0; x < V - 1; x++)

// Finding the minimum key vertex from the

//set of vertices not yet included in MST

48
Hritik Sharma
1902629
Department of Information Technology

int u = min_Key(key, visited);

visited[u] = true; // Add the minimum key vertex to the MST //

Update key and parent arrays

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

// cost[u][v] is non zero only for adjacent vertices of u // visited[v] is

false for vertices not yet included in MST // key[] gets updated only if
cost[u][v] is smaller than key[v] if (cost[u][v]!=0 && visited[v] ==

false && cost[u][v] < key[v]) {

parent[v] = u;

key[v] = cost[u][v];

// print the final MST

print_MST(parent, cost);

// main function

int main()

int cost[V][V];

cout<<"Hritik Sharma"<<endl;

cout<<"1902629"<<endl;

cout<<"Enter the cost/ adjacency matrix for a graph with 6 vertices";

49
Hritik Sharma
1902629

for (int i=0;i<V;i++) { for(int j=0;j<V;j++) {


Department of Information Technology

cin>>cost[i][j];

}
}

find_MST(cost);

return 0;

OUTPUT:

50
Hritik Sharma
1902629
Department of Information Technology

TIME COMPLEXITY:

The time complexity is O(VlogV + ElogV) = O(ElogV), making it the same as Kruskal's
algorithm.
51
Hritik Sharma
1902629

You might also like