Cs3401 - Algorithms Lab Manual
Cs3401 - Algorithms Lab Manual
CS3401 ALGORITHMS
(R2021)
SYLLABUS
COURSE OBJECTIVES:
The student should be made to:
To understand and apply the algorithm analysis techniques on searching and sorting
algorithms.
To critically analyze the efficiency of graph algorithms.
To understand different algorithm design techniques.
To solve programming problems using state space tree.
To understand the concepts behind NP Completeness, Approximation algorithms and
randomized algorithms.
LIST OF EXPERIMENTS
Searching and Sorting Algorithms
1. Implement Linear Search. Determine the time required to search for an element. Repeat the
experiment for different values of n, the number of elements in the list to be searched and plot
a graph of the time taken versus n.
2. Implement recursive Binary Search. Determine the time required to search an element. Repeat
the experiment for different values of n, the number of elements in the list to be searched and
plot a graph of the time taken versus n.
3. Given a text txt [0...n-1] and a pattern pat [0...m-1], write a function search (char pat [ ], char
txt [ ]) that prints all occurrences of pat [ ] in txt [ ]. You may assume that n > m.
4. Sort a given set of elements using the Insertion sort and Heap sort methods and determine the
time required to sort the elements. Repeat the experiment for different values of n, the number
of elements in the list to be sorted and plot a graph of the time taken versus n.
Graph Algorithms
1. Develop a program to implement graph traversal using Breadth First Search.
2. Develop a program to implement graph traversal using Depth First Search.
3. From a given vertex in a weighted connected graph, develop a program to find the shortest
paths to other vertices using Dijkstra’s algorithm.
4. Find the minimum cost spanning tree of a given undirected graph using Prim’s algorithm.
5. Implement Floyd’s algorithm for the All-Pairs- Shortest-Paths problem.
6. Compute the transitive closure of a given directed graph using Warshall's algorithm.
Algorithm Design Techniques
1. Develop a program to find out the maximum and minimum numbers in a given list of n
numbers using the divide and conquer technique.
2. Implement Merge sort and Quick sort methods to sort an array of elements and determine the
time required to sort. Repeat the experiment for different values of n, the number of elements
in the list to be sorted and plot a graph of the time taken versus n.
State Space Search Algorithms
1. Implement N-Queens problem using Backtracking.
Approximation Algorithms Randomized Algorithms
1. Implement any scheme to find the optimal solution for the Traveling Salesperson problem and
then solve the same problem instance using any approximation algorithm and determine the
error in the approximation.
Marks Marks
Evaluation Parameters
Allotted Awarded
Aim & Algorithm: 20
Program: 30
Implementation & Result: 30
Viva Voce: 10
Record: 10
Total: 100
CS3401 ALGORITHMS
Ex. Page Faculty
Date INDEX Marks
No. Number Signature
1 LINEAR SEARCH
2 BINARY SEARCH
4a INSERTION SORT
4b HEAP SORT
7 DIJKSTRA’S ALGORITHM
8 PRIM’S ALGORITHM
9 FLOYD’S ALGORITHM
10 WARSHALL’S ALGORITHM
FINDING MIN AND MAX USING
11
DIVIDE AND CONQUER
12a MERGE SORT
INTRODUCTION TO ALGORITHMS
What is an Algorithm?
Algorithm Basics:
The word Algorithm means ” A set of finite rules or instructions to be followed in calculations or
other problem-solving operations ” Or ” A procedure for solving a mathematical problem in a finite
number of steps that frequently involves recursive operations”.
Therefore Algorithm refers to a sequence of finite steps to solve a particular problem.
Algorithms can be simple and complex depending on what you want to achieve.
It can be understood by taking the example of cooking a new recipe. To cook a new recipe, one
reads the instructions and steps and executes them one by one, in the given sequence. The result
thus obtained is the new dish is cooked perfectly. Every time you use your phone, computer, laptop,
or calculator you are using Algorithms. Similarly, algorithms help to do a task in programming to
get the expected output.
The Algorithms designed are language-independent, i.e. they are just plain instructions that can be
implemented in any language, and yet the output will be the same, as expected.
As one would not follow any written instructions to cook the recipe, but only the standard one.
Similarly, not all written instructions for programming is an algorithms. In order for some
instructions to be an algorithm, it must have the following characteristics:
Clear and Unambiguous: The algorithm should be clear and unambiguous. Each of its steps
should be clear in all aspects and must lead to only one meaning.
Well-Defined Inputs: If an algorithm says to take inputs, it should be well-defined inputs. It may
or may not take input.
Well-Defined Outputs: The algorithm must clearly define what output will be yielded and it
should be well-defined as well. It should produce at least 1 output.
Finite-ness: The algorithm must be finite, i.e. it should terminate after a finite time.
Feasible: The algorithm must be simple, generic, and practical, such that it can be executed with
the available resources. It must not contain some future technology or anything.
Language Independent: The Algorithm designed must be language-independent, i.e. it must be
just plain instructions that can be implemented in any language, and yet the output will be the same,
as expected.
Input: An algorithm has zero or more inputs. Each that contains a fundamental operator must
accept zero or more inputs.
Output: An algorithm produces at least one output. Every instruction that contains a fundamental
operator must accept zero or more inputs.
Definiteness: All instructions in an algorithm must be unambiguous, precise, and easy to interpret.
By referring to any of the instructions in an algorithm one can clearly understand what is to be
done. Every fundamental operator in instruction must be defined without any ambiguity.
Finiteness: An algorithm must terminate after a finite number of steps in all test cases. Every
instruction which contains a fundamental operator must be terminated within a finite amount of
time. Infinite loops or recursive functions without base conditions do not possess finiteness.
Effectiveness: An algorithm must be developed by using very basic, simple, and feasible operations
so that one can trace it out by using just paper and pencil.
Properties of Algorithm:
It should terminate after a finite time.
It should produce at least one output.
It should take zero or more input.
It should be deterministic means giving the same output for the same input case.
Every step in the algorithm must be effective i.e. every step should do some work.
Types of Algorithms:
There are several types of algorithms available. Some important algorithms are:
1. Brute Force Algorithm: It is the simplest approach for a problem. A brute force algorithm is the
first approach that comes to finding when we see a problem.
2. Recursive Algorithm: A recursive algorithm is based on recursion. In this case, a problem is
broken into several sub-parts and called the same function again and again.
3. Backtracking Algorithm: The backtracking algorithm basically builds the solution by searching
among all possible solutions. Using this algorithm, we keep on building the solution following
criteria. Whenever a solution fails we trace back to the failure point and build on the next solution
and continue this process till we find the solution or all possible solutions are looked after.
4. Searching Algorithm: Searching algorithms are the ones that are used for searching elements or
groups of elements from a particular data structure. They can be of different types based on their
approach or the data structure in which the element should be found.
5. Sorting Algorithm: Sorting is arranging a group of data in a particular manner according to the
requirement. The algorithms which help in performing this function are called sorting algorithms.
Generally sorting algorithms are used to sort groups of data in an increasing or decreasing manner.
6. Hashing Algorithm: Hashing algorithms work similarly to the searching algorithm. But they
contain an index with a key ID. In hashing, a key is assigned to specific data.
7. Divide and Conquer Algorithm: This algorithm breaks a problem into sub-problems, solves a
single sub-problem and merges the solutions together to get the final solution. It consists of the
following three steps:
Divide
Solve
Combine
8. Greedy Algorithm: In this type of algorithm the solution is built part by part. The solution of the
next part is built based on the immediate benefit of the next part. The one solution giving the most
benefit will be chosen as the solution for the next part.
9. Dynamic Programming Algorithm: This algorithm uses the concept of using the already found
solution to avoid repetitive calculation of the same part of the problem. It divides the problem into
smaller overlapping subproblems and solves them.
10. Randomized Algorithm: In the randomized algorithm we use a random number so it gives
immediate benefit. The random number helps in deciding the expected outcome.
Advantages of Algorithms:
It is easy to understand.
An algorithm is a step-wise representation of a solution to a given problem.
In Algorithm the problem is broken down into smaller pieces or steps hence, it is easier for
the programmer to convert it into an actual program.
Disadvantages of Algorithms:
Writing an algorithm takes a long time so it is time-consuming.
Understanding complex logic through algorithms can be very difficult.
Branching and Looping statements are difficult to show in Algorithms(imp).
1. The problem that is to be solved by this algorithm i.e. clear problem definition.
2. The constraints of the problem must be considered while solving the problem.
3. The input to be taken to solve the problem.
4. The output to be expected when the problem is solved.
5. The solution to this problem is within the given constraints.
Then the algorithm is written with the help of the above parameters such that it solves the problem.
Example: Consider the example to add three numbers and print the sum.
AIM:
To write a C program to implement Linear Search. Determine the time required to
search for an element. Repeat the experiment for different values of n, the number of
elements in the list to be searched and plot a graph of the time taken versus n.
ALGORITHM:
Step 1 : Declare the necessary variables including the array, the key element to be searched,
and the clock variables to measure the time taken.
Step 2 : Take the input values from the user, including the size of the array, the elements in
the array, and the key element to be searched.
Step 3 : Start the clock and perform the linear search on the given array to find the key
element.
Step 4 : Stop the clock and calculate the time taken to execute the search.
Step 5 : If the key element is found, display its position in the array. Otherwise, display a
message indicating that the search was unsuccessful.
PROGRAM:
linearsearch.c
#include<stdio.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
void main()
{
double t;
int n, i, a[max], k, op, low, high;
clock_t begin, end;
clrscr();
begin = clock();
pos = linsearch(n, a, k);
end = clock();
if(pos == -1)
printf("\n\n Unsuccessful Search");
else
printf("Element %d is found at position %d", k, pos+1);
printf("\n Time taken is %lf CPU cycles \n",(end-begin)/CLK_TCK);
getch();
}
if(i>=n)
return -1;
else
return i;
}
OUTPUT:
Linear Search
Enter the number of elements
5
Enter the elements in any order
12
4
23
54
24
RESULT:
Thus the C program for the implementation of Linear Search was done and
executed successfully. Also the graph for time taken versus n was plotted.
AIM:
To write a C program to implement Recursive Binary Search. Determine the time
required to search an element. Repeat the experiment for different values of n, the number of
elements in the list to be searched and plot a graph of the time taken versus n.
ALGORITHM:
Step 1 : Declare the necessary variables including the array, the key element to be searched,
the low and high index values, and the clock variables to measure the time taken.
Step 2 : Take the input values from the user, including the size of the array, the elements in
the array (in ascending order), and the key element to be searched.
Step 3 : Start the clock and perform the binary search on the given array to find the key
element.
Step 4 : Stop the clock and calculate the time taken to execute the search. If the key element
is found, display its position in the array. Otherwise, display a message indicating
that the search was unsuccessful.
PROGRAM:
binarysearch.c
#include<stdio.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
#define max 100
int pos;
int binsearch (int,int[],int,int,int);
int linsearch (int,int[],int);
void main()
{
double t;
int n,i,a [max],k,op,low,high,pos;
clock_t begin,end;
clrscr();
printf("\nBinary Search \n");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
low = 0;
high = n-1;
begin = clock();
pos = binsearch(n,a,k,low,high);
end = clock();
if(pos == -1)
printf("\n\nUnsuccessful Search");
else
printf("\n Element %d is found at position %d", k, pos+1);
getch();
}
OUTPUT:
Binary Search
RESULT:
Thus the C program for the implementation of Binary Search was done and
executed successfully. Also the graph for time taken versus n was plotted.
AIM:
To write a C program to implement Naïve Pattern Matching - For the given text
txt[0...n-1] and the pattern pat[0...m-1], write a function search(char pat [ ], char txt [ ]) that
prints all occurrences of pat[ ] in txt[ ]. You may assume that n > m.
ALGORITHM:
PROGRAM:
#include <stdio.h>
#include <string.h>
if (j == M)
printf("Pattern found at index %d \n", i);
}
}
int main()
{
char txt[] = "AABAACAADAABAAABAA";
search(pat, txt);
return 0;
}
OUTPUT:
Text
AABAACAADAABAAABAA
Pattern
AABA
--------------------------------
Process exited after 0.2837 seconds with return value 0
.
RESULT:
Thus the C program for the implementation of Naïve Pattern Matching was done
and executed successfully.
AIM:
To write a C program to sort a given set of elements using the Insertion Sort and
determine the time the time required to sort the elements. Repeat the experiment for different
values of n, the number of elements in the list to be sorted and plot a graph of the time taken
versus n.
ALGORITHM:
Step 1 : Start iterating from the second element of the array to the last element.
Step 2 : For the current element, store it in a temporary variable.
Step 3 : Compare the current element with the previous element and swap them if the
previous element is greater than the current element.
Step 4 : Repeat the previous step until the beginning of the array is reached or the previous
element is no longer greater than the current element.
Step 5 : Insert the current element at its correct position in the array.
Step 6 : Repeat steps 2-5 until the entire array is sorted.
PROGRAM:
insertionsort.c
int main()
{
int a[] = { 12, 31, 25, 8, 32, 17 };
clock_t begin,end;
int n = sizeof(a) / sizeof(a[0]);
begin = clock();
insertionsort(a, n);
end = clock();
return 0;
}
OUTPUT:
RESULT:
Thus the C program for the implementation of Insertion Sort was done and
executed successfully. Also the graph for time taken versus n was plotted.
AIM:
To write a C program to sort a given set of elements using the Heap Sort and
determine the time the time required to sort the elements. Repeat the experiment for different
values of n, the number of elements in the list to be sorted and plot a graph of the time taken
versus n.
ALGORITHM:
Step 1: Read the number of elements (n) and the elements (arr[]) from the user
Step 2: Call the heapsort() function with n and arr[] as arguments
Step 3: In the heapsort() function, call the heapy() function with n and arr[] as arguments
Step 4: In the heapsort() function, for each element i from n to 1, swap the element at index 1
(root) with the element at index i, and then call the adjust() function with i-1 and arr[]
as arguments to restore the heap property
Step 5: In the heapy() function, for each element i from 1 to n, insert the element into the
heap by repeatedly swapping it with its parent until it is in the correct position
PROGRAM:
heapsort.c
// C program for Heap Sort
#include<stdio.h>
#include<conio.h>
#include<time.h>
arr[j] = item;
}
}
while(i<n)
{
if((i+1) < n)
{
if(arr[i] < arr[i+1])
i++;
}
void main()
{
int i, n, arr[50];
clock_t end, start;
clrscr();
start = clock();
heapsort(n, arr);
end = clock();
OUTPUT:
RESULT:
Thus the C program for the implementation of Heap Sort was done and executed
successfully. Also the graph for time taken versus n was plotted.
AIM:
To write a C program to implement graph traversal using Breadth First Search.
ALGORITHM:
Step 1: Read the value of n and the adjacency matrix a[n][n] from the user
Step 2: Read the start node from the user, initialize the queue q[20], the visited array r[20],
and the start and end indices of the queue (st=0, ed=0)
Step 3: Enqueue the start node in the queue and mark it as visited in the visited array
Step 4: While the queue is not empty, repeat the following steps:
- Dequeue a node from the front of the queue
- For each adjacent node of the dequeued node that has not been visited yet, mark it as
visited, enqueue it in the queue, and print it as a reachable node from the start node
Step 5: If all nodes have been visited, print a message indicating that all nodes are reachable
from the start node. Otherwise, print a message indicating that not all nodes are
reachable from the start node.
PROGRAM:
#include<stdio.h>
#include<conio.h>
void main()
{
int q[20], a[20][20], r[20], st=0, ed=0, start, n, i, j;
clrscr();
printf("\nEnter the value of n: ");
scanf("%d", &n);
printf("\nEnter the adjacency matrix: \n ");
while(st != ed)
{
for(i=0; i<n; i++)
{
if((r[i] == 0) && a[q[st]][i] == 1)
{
q[ed++]=i;
r[i]=1;
printf("%d ",i+1);
}
}
st++;
}
if(ed != n)
{
printf("\nAll nodes are not reachable from origin!!");
}
getch();
}
OUTPUT:
RESULT:
Thus the C program for the implementation of graph traversal using Breadth First
Search was done and executed successfully.
AIM:
To write a C program to implement graph traversal using Depth First Search.
ALGORITHM:
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int vertexNumber;
struct node *pointerToNextVertex;
};
struct Graph
{
int numberOfVertices;
int *visitedRecord;
struct node **adjacencyLists;
};
graph->adjacencyLists[source] = newNode;
newNode = createNodeForList(source);
newNode->pointerToNextVertex = graph->adjacencyLists[destination];
graph->adjacencyLists[destination] = newNode;
}
return graph;
}
int main()
{
int numberOfVertices, numberOfEdges, i;
int source, destination;
int startingVertex;
OUTPUT:
DFS Traversal: 2 3 5 4 0 1
RESULT:
Thus the C program for the implementation of graph traversal using Depth First
Search was done and executed successfully.
AIM:
To develop a C program to find the shortest paths from a given vertex in a weighted
connected graph, to other vertices using Dijkstra’s algorithm.
ALGORITHM:
Step 1 : Define the macro INFINITY and the maximum size of the matrix as MAX.
Step 2 : Define the function dijkstra that takes the adjacency matrix, the number of vertices,
and the starting node as inputs.
Step 3 : Declare the variables cost, distance, pred, visited, count, mindistance, nextnode, i,
and j.
Step 4 : Initialize the cost matrix with the weights of the edges or infinity if there is no edge
between two nodes.
Step 5 : Initialize the distance, pred, and visited arrays with the information of the starting
node.
Step 6 : Use a loop to find the shortest path to all nodes by selecting the node with the
minimum distance from the starting node and updating the distance and pred arrays
accordingly.
Step 7 : Print the shortest distance and path from the starting node to all the other nodes in
the graph.
PROGRAM:
#include<stdio.h>
#define INFINITY 9999
#define MAX 10
int main()
{
int G[MAX][MAX],i,j,n,u;
printf("Enter no. of vertices: ");
scanf("%d",&n);
printf("\nEnter the adjacency matrix:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&G[i][j]);
printf("\nEnter the starting node: ");
scanf("%d",&u);
dijkstra(G,n,u);
return 0;
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(G[i][j]==0)
cost[i][j]=INFINITY;
else
cost[i][j]=G[i][j];
for(i=0;i<n;i++)
{
distance[i]=cost[startnode][i];
pred[i]=startnode;
visited[i]=0;
}
distance[startnode]=0;
visited[startnode]=1;
count=1;
while(count<n-1)
{
mindistance=INFINITY;
for(i=0;i<n;i++)
if(distance[i]<mindistance&&!visited[i])
{
mindistance=distance[i];
nextnode=i;
}
visited[nextnode]=1;
for(i=0;i<n;i++)
if(!visited[i])
if(mindistance+cost[nextnode][i]<distance[i])
{
distance[i]=mindistance+cost[nextnode][i];
pred[i]=nextnode;
}
count++;
}
for(i=0;i<n;i++)
if(i!=startnode)
{
printf("\nDistance of node %d = %d ",i,distance[i]);
printf("\nPath = %d ",i);
j=i;
do
{
j=pred[j];
printf(" <- %d ",j);
}while(j!=startnode);
}
}
OUTPUT:
Distance of node 1 = 10
Path = 1 <- 0
Distance of node 2 = 50
Path = 2 <- 3 <- 0
Distance of node 3 = 30
Path = 3 <- 0
Distance of node 4 = 60
Path = 4 <- 2 <- 3 <- 0
..
RESULT:
Thus the C program for the implementation of Dijkstra’s algorithm was done and
executed successfully.
AIM:
To write a C program to find the minimum cost spanning tree of a given undirected
graph using Prim’s algorithm.
ALGORITHM:
Step 1 : Initialize the adjacency matrix 'G' and the spanning tree matrix 'spanning' with size
'MAX' and 'n'.
Step 2 : Read the number of vertices 'n' and the adjacency matrix 'G' from the user.
Step 3 : Initialize the 'distance', 'visited', 'from', and 'cost' arrays.
Step 4 : Set the 'distance' of the first vertex to 0 and mark it as 'visited'.
Step 5 : Traverse through all the vertices, find the minimum distance and mark it as 'visited'.
Step 6 : Update the 'distance' and 'from' arrays based on the minimum distance.
Step 7 : Continue the above process until all the edges are traversed and return the minimum
cost of the spanning tree.
PROGRAM:
// C program for Prim’s algorithm.
#include<stdio.h>
#include<stdlib.h>
#define infinity 9999
#define MAX 20
int G[MAX][MAX],spanning[MAX][MAX],n;
int prims();
int main()
{
int i,j,total_cost;
printf("Enter no. of vertices: ");
scanf("%d",&n);
printf("\nEnter the adjacency matrix:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&G[i][j]);
total_cost=prims();
printf("\nSpanning Tree Matrix:\n");
for(i=0;i<n;i++)
{
printf("\n");
for(j=0;j<n;j++)
printf("%d\t",spanning[i][j]);
}
printf("\n\nTotal cost of minimum spanning tree = %d",total_cost);
return 0;
}
int prims()
{
int cost[MAX][MAX];
int u,v,min_distance,distance[MAX],from[MAX];
int visited[MAX],no_of_edges,i,min_cost,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(G[i][j]==0)
cost[i][j]=infinity;
else
cost[i][j]=G[i][j];
spanning[i][j]=0;
}
distance[0]=0;
visited[0]=1;
for(i=1;i<n;i++)
{
distance[i]=cost[0][i];
from[i]=0;
visited[i]=0;
}
min_cost=0;
no_of_edges=n-1;
while(no_of_edges>0)
{
min_distance=infinity;
for(i=1;i<n;i++)
if(visited[i]==0&&distance[i]<min_distance)
{
v=i;
min_distance=distance[i];
}
u=from[v];
spanning[u][v]=distance[v];
spanning[v][u]=distance[v];
no_of_edges--;
visited[v]=1;
for(i=1;i<n;i++)
if(visited[i]==0&&cost[i][v]<distance[i])
{
distance[i]=cost[i][v];
from[i]=v;
}
min_cost=min_cost+cost[u][v];
}
return(min_cost);
}
OUTPUT:
0 2 1 0 0 0
2 0 0 0 3 0
1 0 0 0 0 4
0 0 0 0 0 2
0 3 0 0 0 0
0 0 4 2 0 0
RESULT:
Thus the C program for the implementation of Prim’s algorithm was done and
executed successfully.
AIM:
To write a C program to implement Floyd’s algorithm for the All-Pairs-Shortest-Paths
problem.
ALGORITHM:
Step 1 : Define a function min() that takes two integers as input and returns the minimum of
the two.
Step 2 : Define a function floyds() that takes a 2D array of integers p and an integer n as
input. This function computes the shortest path between every pair of vertices in a
given weighted graph using Floyd's algorithm.
Step 3 : Inside the floyds() function, initialize the diagonal of the input matrix to 0 and
initialize all other elements to a very large value, e.g., 999.
Step 4 : Using a nested loop, iterate through all vertices and compute the shortest path
between them using the Floyd's algorithm.
Step 5 : Inside the main() function, read the number of vertices n and the number of edges e
of the graph from the user and initialize the input matrix p to 999 for all elements.
Step 6 : Read the end vertices and the weight of each edge from the user and update the
corresponding element in the input matrix p.
Step 7: Print the input matrix, the distance matrix obtained from floyds() function, and the
shortest paths between every pair of vertices.
PROGRAM:
void main()
{
int p[10][10],w,n,e,u,v,i,j;
printf("\n Enter the number of vertices: ");
scanf("%d",&n);
printf("\n Enter the number of edges: ");
scanf("%d",&e);
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
p[i][j]=999;
}
for (i=1;i<=e;i++)
{
printf("\n Enter the end vertices of edge %d with its weight \n ",i);
scanf("%d%d%d",&u,&v,&w);
p[u][v]=w;
}
floyds(p,n);
OUTPUT:
Distance Matrix:
0 10 3 4
2 0 5 6
7 7 0 1
6 16 9 0
RESULT:
Thus the C program for the implementation of Floyd’s algorithm was done and
executed successfully.
AIM:
To write a C program to compute the transitive closure of a given directed graph
using Warshall's algorithm.
ALGORITHM:
Step 1 : Define a function Warshall’s that takes in the adjacency matrix p and the number of
vertices n as input.
Step 2 : Initialize variables i, j, and k to zero.
Step 3 : Use three nested loops, with k running from 1 to n, i running from 1 to n, and j
running from 1 to n.
Step 4 : Inside the innermost loop, update p[i][j] as follows:
p[i][j] = (p[i][j] || (p[i][k] && p[k][j])).
Step 5 : Define the main function, which takes in the number of vertices n and the number of
edges e as input.
Step 6 : Initialize the adjacency matrix p to zero for all elements using two nested for loops.
Step 7 : Inside a loop, take input for the end vertices of each edge and update the adjacency
matrix p accordingly. Finally, call the Warshall’s function passing the adjacency
matrix p and number of vertices n as arguments. Finally, print the transitive closure
of the graph.
PROGRAM:
#include<stdio.h>
void main()
{
int p[10][10],n,e,u,v,i,j;
printf("\n Enter the number of vertices: ");
scanf("%d",&n);
printf("\n Enter the number of edges: ");
scanf("%d",&e);
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
p[i][j]=0;
}
for (i=1;i<=e;i++)
{
printf("\n Enter the end vertices of edge %d \n ",i);
scanf("%d%d",&u,&v);
p[u][v]=1;
}
printf("\n Matrix of input data:\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%d \t",p[i][j]);
printf("\n");
}
warshalls(p,n);
OUTPUT:
Transitive Closure:
1 1 1 1
1 1 1 1
0 0 0 0
1 1 1 1
RESULT:
Thus the C program for the implementation of Warshall's algorithm was done and
executed successfully.
Ex. No.: 11 FINDING MIN AND MAX USING DIVIDE AND CONQUER
AIM:
To write a C program to find out the maximum and minimum numbers in a given list
of n numbers using the divide and conquer technique.
ALGORITHM:
Step 1 : Declare integer variables max, min and an integer array a of size 100
Step 2 : Define a function named maxmin which takes two integer parameters i and j
Step 3 : In the maxmin function, if i is equal to j, set max and min equal to a[i]
Step 4 : Otherwise, if i is equal to j-1, compare a[i] and a[j] to determine max and min
Step 5 : If i is neither equal to j nor j-1, recursively call the maxmin function by dividing the
array into two halves, calculate the max and min for each half, and then compare the
max and min of the two halves to determine the final max and min for the entire
array
Step 6 : In the main function, read the number of elements in the array from the user, read the
array elements from the user, call the maxmin function with appropriate arguments
and print the minimum and maximum values of the array.
PROGRAM:
if(i == j)
{
max = min = a[i];
}
else
{
if(i == j-1)
{
if(a[i] <a[j])
{
max = a[j];
min = a[i];
}
else
{
max = a[i];
min = a[j];
}
}
else
{
mid = (i+j) / 2;
maxmin(i, mid);
max1 = max; min1 = min;
maxmin(mid+1, j);
int main()
{
int i, num;
printf ("\nEnter the total number of numbers : ");
scanf ("%d", &num);
printf ("Enter the numbers : \n");
max = a[0];
min = a[0];
maxmin(1, num);
printf ("Minimum element in an array: %d\n", min);
printf ("Maximum element in an array: %d\n", max);
return 0;
}
OUTPUT:
RESULT:
Thus the C program for the implementation of finding min and max numbers in a
given list using divide and conquer technique was done and executed successfully.
AIM:
To write a C program to implement Merge sort method to sort an array of elements
and determine the time required to sort. Repeat the experiment for different values of n, the
number of elements in the list to be sorted and plot a graph of the time taken versus n.
ALGORITHM
Step 1: Read number of elements n to sort
Step 2: Read n number of elements
Step 3: Calculate mid = (i + j) / 2
Step 4: merge_sort(i, mid, a, aux)
Step 5: merge_sort(mid + 1, j, a, aux)
Step 6: pointer_left = i, pointer_right = mid + 1
Step 7: for k in [i ... j]
if pointer_left points to smaller element,
aux[k] = a[pointer_left] and
increment pointer_left by 1
if pointer_right points to smaller element,
aux[k] = a[pointer_right] and
increment pointer_right by 1
copy the contents of aux[i .. j] to a[i .. j]
Step 8: Print sorted numbers
PROGRAM
#include <stdio.h>
#include <time.h>
int mid = (i + j) / 2;
int pointer_left = i;
int pointer_right = mid + 1;
int k;
int main()
{
int a[100], aux[100], n, i, d, swap;
clock_t begin, end;
printf("Enter number of elements in the array:\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
begin = clock();
merge_sort(0, n - 1, a, aux);
end = clock();
OUTPUT
Enter 10 integers
12
56
34
25
867
4
967
123
78
566
RESULT:
Thus the C program for the implementation of Merge Sort was done and executed
successfully. Also the graph for time taken versus n was plotted.
AIM:
To write a C program to implement Quick sort method to sort an array of elements
and determine the time required to sort. Repeat the experiment for different values of n, the
number of elements in the list to be sorted and plot a graph of the time taken versus n.
ALGORITHM:
Step 1: Define a function quicksort() which accepts an array, the index of the first and last
element as arguments.
Step 2: If the first index is less than the last index, then select the first element as the pivot
element.
Step 3: Initialize two variables i and j to the first and last index respectively.
Step 4: Increment i until number[i] is greater than the pivot element, and decrement j until
number[j] is less than the pivot element.
Step 5: Swap the values of number[i] and number[j].
Step 6: Recursively call the quicksort() function for the two sub-arrays on both sides of the
pivot element.
Step 7: In the main function, accept input for the number of elements and the elements of the
array. Call the quicksort() function passing the array and the indices of the first and
last element. Print the sorted array and the time taken to execute the program.
PROGRAM:
#include<stdio.h>
#include <time.h>
while(i<j)
{
if(i < j)
{
temp=number[i];
number[i]=number[j];
number[j]=temp;
}
}
temp=number[pivot];
number[pivot]=number[j];
number[j]=temp;
quicksort(number,first,j-1);
quicksort(number,j+1,last);
}
}
int main()
{
int i, n, number[50];
clock_t begin, end;
for(i=0;i<n;i++)
scanf("%d",&number[i]);
begin = clock();
quicksort(number,0,n-1);
end = clock();
for(i=0;i<n;i++)
printf(" %d",number[i]);
OUTPUT:
Enter value of n: 10
Enter 10 elements:
76
45
78
98
45
23
686
5454
5
21
RESULT:
Thus the C program for the implementation of Quick Sort was done and executed
successfully. Also the graph for time taken versus n was plotted.
AIM:
To write a C program to implement N-Queens problem using Backtracking.
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<math.h>
int board[20],count;
int main()
{
int n,i,j;
void queen(int row,int n);
void print(int n)
{
int i,j;
printf("\n\nSolution %d:\n\n",++count);
for(i=1;i<=n;++i)
printf("\t%d",i);
for(i=1;i<=n;++i)
{
printf("\n\n%d",i);
for(j=1;j<=n;++j)
{
if(board[i]==j)
printf("\tQ");
else
printf("\t-");
}
}
}
return 1;
}
OUTPUT:
Solution 1:
1 2 3 4
1 - Q - -
2 - - - Q
3 Q - - -
4 - - Q -
Solution 2:
1 2 3 4
1 - - Q -
2 Q - - -
3 - - - Q
4 - Q - -
RESULT:
Thus the C program for the implementation of N-Queens problem using
Backtracking was done and executed successfully.
AIM:
To write a C program to implement any scheme to find the optimal solution for the
Traveling Salesperson problem and then solve the same problem instance using any
approximation algorithm and determine the error in the approximation.
ALGORITHM:
PROGRAM:
void takeInput()
{
int i,j;
completed[i] = 0;
}
printf("\n\nThe cost list is: ");
if(ncity == 999)
{
ncity = 0;
printf("%d", ncity+1);
cost += ary[city][ncity];
return;
}
mincost(ncity);
}
int least(int c)
{
int i, nc = 999;
int min = 999, kmin;
if(min != 999)
cost += kmin;
return nc;
}
int main()
{
takeInput();
return 0;
}
tspapprox.c
#include<stdio.h>
int c = 0,cost = 999;
if (i == n)
{
copy_array(a, n);
}
else
{
for (j = i; j <= n; j++)
{
swap((a + i), (a + j));
permute(a, i + 1, n);
swap((a + i), (a + j));
}
}
}
int main()
{
int i, j;
int a[] = {0, 1, 2, 3};
permute(a, 0, 3);
printf("minimum cost: %d",cost);
OUTPUT:
Output of tsp.c
Output of tspaprox.c
minimum cost: 7
Error:
Error in Approximation = 0
RESULT:
Thus the C program for the implementation of Traveling Salesperson Problem
was done and executed successfully.
AIM:
To write a C program to implement randomized algorithm for finding the kth smallest
number.
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
int N = 20;
int A[20];
return j - 1;
}
scanf("%d", &k);
quick_sort(0, N, k);
}
OUTPUT:
RESULT:
Thus the C program for the implementation of randomized algorithm for finding
th
the k smallest number was done and executed successfully.
AIM:
To write a C program to find whether a Directed Graph is Cyclic or not.
ALGORITHM:
Step 1 − Visit the adjacent unvisited vertex. Mark it as visited. Display it. Push it in a stack.
Step 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.)
Step 3 − Repeat Step 1 and Step 2 until the stack is empty.
PROGRAM:
void DF_Traversal()
{
int v;
for(v=0; v<n; v++)
state[v] = initial;
DFS(0);/*start DFS from vertex 0*/
for(v=0; v<n; v++)
{
if(state[v]==initial)
DFS(v);
}
printf("\nGraph is Acyclic\n");
}/*End of DF_Traversal( )*/
void DFS(int v)
{
int i;
state[v] = visited;
void create_graph()
{
int i,max_edges,origin,destin;
OUTPUT:
Graph is Acyclic
RESULT:
Thus the C program for the implementation of finding cycle in a directed graph
was done and executed successfully.
AIM:
To write a C++ program to implement Job Assignment Problem using Branch and
Bound technique.
ALGORITHM:
while (true)
{
// Find a live node with least estimated cost
E = Least();
if (E is a leaf node)
{
printSolution();
return;
}
PROGRAM:
#include <bits/stdc++.h>
#define N 4
node->assigned[y] = true;
node->parent = parent;
node->workerID = x;
node->jobID = y;
return node;
}
minIndex = j;
min = costMatrix[i][j];
}
}
cost += min;
available[minIndex] = false;
}
return cost;
}
struct comp
{
bool operator()(const Node* lhs, const Node* rhs) const
{
return lhs->cost > rhs->cost;
}
};
printAssignments(min->parent);
cout << "Assign Worker " << char(min->workerID + 'A')
<< " to Job " << min->jobID << endl;
}
while (!pq.empty())
{
Node* min = pq.top();
pq.pop();
int i = min->workerID + 1;
if (i == N)
{
printAssignments(min);
return min->cost;
}
child->cost = child->pathCost +
calculateCost(costMatrix, i, j, child->assigned);
pq.push(child);
}
}
}
}
// Driver code
int main()
{
// x-coordinate represents a Worker
// y-coordinate represents a Job
int costMatrix[N][N] =
{
{9, 2, 7, 8},
{6, 4, 3, 7},
{5, 8, 1, 8},
{7, 6, 9, 4}
};
return 0;
}
OUTPUT:
Optimal Cost is 13
RESULT:
Thus the C++ program for the implementation of Job Assignment Problem using
Branch and Bound technique was done and executed successfully.