0% found this document useful (0 votes)
18 views26 pages

Daa Lab File

Uploaded by

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

Daa Lab File

Uploaded by

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

BUNDELKHAND INSTITUTE OF

ENGINEERING AND TECHNOLOGY


JHANSI

SESSION: 2024-2025

NAME:- AMAN

BRANCH:- COMPUTER SCIENCE AND


ENGINEERING

SUBJECT:- DESIGN AND ANALYSIS OF


ALGORITHM LAB (BCS-553)
SEMESTER:- 5th

ROLL NUMBER:- 2200430100006

INDEX

S.NO. DATE TITLE SIGN.


01. 05/08/24 To implement the Bubble, Insertion and Selection Sort and analyze
the time complexity from its graph

02. 12/08/24 To implement the Linear Search and Binary Search and find the
number of comparisons and analyze the time complexity from its
graph.

03. 02/09/24 To implement the CountingSort and Radix Sort and analyze the
time complexity from its graph.

04. 09/09/24 To implement the Heap Sort and analyze the time complexity from
its graph.

05. 23/09/24 To implement the Merge Sort and Quick Sort algorithm and
analyze the time complexity from its graph.

06. 30/09/24 To find the maximum and minimum numbers in a given array.

07. 07/10/24 To find the Kth smallest number in a given array .

08. 14/10/24 To implement the Prim’s Algorithm to find a Minimum Spanning


Tree.

09. 21/10/24 To implement the Kruskal’ s Algorithm to find a Minimum


Spanning Tree

10. 28/10/24 To implement Matrix Chain Multiplication using Dynamic


Programming .

11. 11/11/24 To implement Longest Common Subsequence Problem


using Dynamic Programming .

12. 18/11/24 To do the case study of P , NP , NP Complete , NP Hard


Problem.
Practical-01
Objective: To implement the Bubble, Insertion and Selection Sort and
analyze thetime complexity from its graph.

Bubble Sort

Code:

#include<bits/stdc++.h>
#include<ctime>
using namespace std;
int main(){
freopen("random.txt","r",stdin); int
ran[]={10000,20000,30000,40000,80000,100000,120000,150000,180000,200000 }
; int ts[10];
for(int i=0;i<10;i++){

int n=ran[i];

int curr=time(NULL);
int arr[n];
for(int i=0;i<n;i++){

cin>>arr[i];

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

for(int j=0;j<n-i-1;j++){

if(arr[j+1],arr[j])

swap(arr[j],arr[j+1]);
}

}
ts[i]=time(NULL)-curr;
cout<<ts[i]<<" ";
}

return 0;
Bubble_S
} 100
0

Graph: 80
0

60
0

40
10000 20000 30000 40000 80000 100000 120000 150000
Selection Sort:
Best Avg Worst
Code:

#include<bits/stdc++.h>
#include<ctime>
using namespace std;
int main(){
freopen("File2.txt","r",stdin); int
ran[]={10000,20000,30000,40000,80000,100000,120000,150000,180000,200000 }

1
; int ts[10];
for(int i=0;i<10;i++){

int n=ran[i];
int curr=time(NULL);
int arr[n];
for(int i=0;i<n;i++){

cin>>arr[i];

for (int i = 0; i < n-1; i++){


int min_idx = i;

for (int j = i+1; j < n; j++){if (arr[j]

< arr[min_idx]) min_idx = j;

}
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
ts[i]=time(NULL)-curr; cout<<ts[i]<<" ";
}

return 0;

SELECTION_SO
70
0
60
0
50
0
40
0
1000 2000 3000 4000 80000 100000 120000 150000 180000
Best Avg Worst

Insertion Sort
#include <bits/stdc+
+.h> #include
<fstream> #include
<stdio.h> #include
<string> #include
<time.h>
using namespace std;
int main(void)
{
clock_t
start_b,end_b;
double t;
vector<int>
a(100000); int i = 0;
FILE *f;
2
if (f = fopen("random.txt", "r")){
while (fscanf(f, "%d", &a[i]) != EOF){
if(i>a.size()
) break;
i++;
}
fclose(f);
start_b
=clock(); int i,
key, j;
for (i = 1; i < z*10000; i++)
{
key
=a[i]; j =
i - 1;
while (j >= 0 && a[j] > key)
{
a[j + 1] =
a[j]; j = j - 1;
}
a[j + 1] = key;
}
end_b=clock();
for(int
i=0;i<100000;i++)
cout<<a[i]<<endl;
t=((double)(end_b-start_b))/CLOCKS_PER_SEC;
cout<<t;

}
return 0; INSERTIO
2
} 0
0
Graph
15
0

10 100 200 300 400 50000 100000 120000


Best Avg Worst

Practical-02
Objective: To implement the Linear Search and Binary Search and find the
number ofcomparisons and analyze the time complexity from its graph.

Linear Search
#include <bits/stdc+
+.h> #include
<fstream> #include
<stdio.h> #include
<string> #include
<time.h>
using namespace
std; int main(void)
{ clock_t
start_b,end_b; double
3
t;
vector<int>
a(100000); int i = 0;
FILE *f;
if (f = fopen("file1.txt", "r"))
while (fscanf(f, "%d", &a[i]) != EOF){
if(i>a.size()
) break;
i++;
}
fclose(f);
for(int z=1;z<11;z++)
{
int
x=10;
int c=0;
for(int i=0;i<z*10000;i++){ GRAPH
if(a[i]==x){
break;
}
else c++;
}
cout<<c<<endl;
}
}
return 0;
}

Binary Search
#include <bits/stdc+
+.h> #include
<fstream> #include
<stdio.h> #include
<string> #include
<time.h>
using namespace
std; int main(void)
{
clock_t
start_b,end_b;
double t;
vector<int>
a(100000); int i = 0;
FILE *f;
if (f = fopen("file1.txt", "r"))
{
while (fscanf(f, "%d", &a[i]) != EOF)
{
if(i>a.size()
) break;
4
i++;
}
fclose(f);
for(int z=1;z<11;z++)
{
int
x=1000;
int c=0;
int
l=0,r=z*10000;
while (l <= r) {
int m = l + (r - l) /
2; if (a[m] == x)
{c
++;
cout<<m<<endl;
}
if (a[m] < x){
l=m+
1;
c++;
}
else{ BINARY
r=m-
18
1; c++;
16
}
14
}
12
cout<<c<<endl;
10
}
8
}
return 0; 6
} 4
2
0
50000 35000 20000 15000 10000 5000 4000 3000 2500

Practical-03
Objective: To implement the CountingSort and Radix Sort and
analyze thetime complexity from its graph.

Count Sort
#include <bits/stdc+
+.h> #include
<fstream> #include
<stdio.h> #include
<string> #include
<time.h>
using namespace std;
void countingsort(vector<int>&vt,int n,int
t){ long int arr[t+1];
long int c[n];
for(int i=0;i<=t;i+
+){ arr[i]=0;
}
5
for(int i=0;i<n;i+
+){ arr[vt[i]]++;
}
for(int
i=1;i<=t;i++){
arr[i]=arr[i]+arr[i-
1];
}
for(int i=n-1;i>=0;i--){
c[--arr[vt[i]]]=vt[i];
}
}
int main(){
freopen("count.txt","r",stdi
n); vector<int>
vt1(100000); for(int
i=0;i<100000;i++){
cin>>vt1[i];
}
int
Range[10]={100000,90000,80000,70000,60000,50000,40000,30000,20000,10000};
for(int i=0;i<10;i++)
{ cloct_t
start,end; int
tests=Range[i];
vector<int>vt=v
t1; start=clock();
countingsort(vt,tests-
1,10); end=clock();
double total_time=double(end-start)/CLOCTS_PER_SEC;
cout<<"time taken for "<<tests<<" inputs is :
"<<total_time<<endl;
}
}

Radix Sort
#include <bits/stdc+
+.h> #include
<fstream> #include
<stdio.h> #include
<string> #include
<time.h>
using namespace std;
void print(vector<string>& st, int n)
{
for (int i = 0; i < n; i+
+) { cout << st[i] <<
" ";
}
cout <<endl;
}
int char_at(string st, int k)

6
{
if (st.size() <=
k) return -1;
else
return st.at(k);
}
void radix sort(vector<string>& st, int lo, int hi,
int k) {
if (hi <= lo)
{ return;
}
int count[256 + 2] = { 0 };
unordered_map<int, string>
temp; for (int i = lo; i <= hi; i+
+) {
int c = char_at(st[i],
k); count[c+2]++;
}
for (int r = 0; r < 256 + 1;
r++) count[r + 1] +=
count[r];
for (int i = lo; i <= hi; i+
+) { int c = char_at(st[i],
k); temp[count[c+1]++]
= st[i];
}
for (int i = lo; i <= hi;
i++) st[i] = temp[i -
lo];
for (int r = 0; r < 256; r++)
radixsort(st, lo + count[r], lo + count[r + 1] - 1,k + 1);
}
int main()
{
freopen("radix.txt","r",stdin)
; vector<string>
v1(100000); for(int
i=0;i<100000;i++)
cin>>v1[i];
int range[10]={1000,2000,3000,4000,5000,6000,7000,8000,9000,10000};
for(int i=0;i<10;i++)
{ clock_t ti,tf;
int inputs=range[i];
vector<string>v=v1;
v.resize(inputs);
ti=clock();
radixsort(v,0,inputs-
1,0); tf=clock();
double tt=double(tf-ti)/CLOCKS_PER_SEC;
//print(v,inputs);
cout<<"
"<<tt<<endl;

7
}
}
Practical-04
Objective: To implement the Heap Sort and analyze the time
complexity from its graph.

Heap Sort
#include <bits/stdc+
+.h> #include
<fstream> #include
<string> #include
<stdio.h>
using namespace

std; #include

<time.h

void heapify(vector<int>arr, int N, int i)


{
int largest = i;
int l = 2 * i + 1;
int r = 2 * i + 2;
if (l < N && arr[l] >
arr[largest]) largest
= l;

if (r < N && arr[r] >


arr[largest]) largest = r;
if (largest != i) {
swap(arr[i],
arr[largest]);
heapify(arr, N, largest);
}
}
void heapSort(vector<int>arr, int N)
{
for (int i = N / 2 - 1; i >= 0;
i– heapify(arr, N, i);
for (int i = N - 1; i > 0; i--) {
swap(arr[0], arr[i]);
heapify(arr, i, 0);
}
}
int main(void)
{
clock_t start, end;
double
cpu_time_used;
vector<int>v(100000)
;
int i = 0;
FILE *file;
if (file = fopen("f2.txt", "r"))
{ int x;
while (fscanf(file, "%d", &v[i]) != EOF)
8
{
if(i>v.size(
)) break;
i++;

}
fclose(file);
int
n=v.size();
int hold;
start =
clock();
heapSort(v, n);
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
cout<<cpu_time_used }
return 0;
}
BEST CASE AVERAGE WORST C
CASE

0.14 0.187 0.343 10000

0.281 0.375 0.906 20000

0.453 1.319 7.17 30000

0.734 2.765 13.386 40000

1.249 3.921 18.527 50000

2.062 7.326 37.096 60000

5.374 14.662 68.875 70000

8.455 21.41 96.808 80000

7.905 27.321 120.814 90000

14.069 33.523 146.732 100000

Practical-05
Objective: To implement the Merge Sort and Quick Sort algorithm and analyze
the timecomplexity from its graph.

Merge Sort
#include <bits/stdc+
+.h> #include
<fstream> #include
<stdio.h>
using namespace
std; #include
<time.h>
void merge(vector<int>a, int x, int b, int c) {
int n1 = b- x +
1; int n2 = c-b;
int L[n1], M[n2];
for (int i = 0; i < n1;
9
i++) L[i] = a[l+ i];
for (int j = 0; j < n2;
j++) M[j] = a[b + 1 +
j];
int i, j,
k; i = 0;
j = 0;
k = x;
while (i < n1 && j <
n2) { if (L[i] <= M[j]) {
a[k] =
L[i]; i++;
} else {
a[k] =
M[j]; j++;
}
k+
+;
}
while (i < n1)
{ a[k] =
L[i]; i++;
k++;
}
while (j < n2)
{ a[k] = M[j];
j++;
k++;
}
}
void mergeSort(vector<int>a, int l, int
r) { if (l < r) {
int m = l + (r - l) / 2;
mergeSort(a, l, m);
mergeSort(a, m + 1,
r); merge(a, l, m, r);
}
}
int main(void)
{
clock_t
start,end;
double t;
vector<int>
v(10000); int i = 0;
FILE *file;
if (file = fopen("random.txt", "r"))
{
int x;
while (fscanf(file, "%d", &v[i]) != EOF)
{
if(i>v.size(
10
)) break;
i++;
}
fclose(file);
int
n=v.size();
start
=clock();
mergeSort(v,0,n-
1); end=clock();
t=((double)(end-start))/CLOCKS_PER_SEC;
cout<<t;
}
return 0;
}

BEST CASE AVERAGE WORST C


CASE

0.53 0.35 0.36 10000

1.6 1.12 1.52 20000

1.82 1.95 1.96 30000

3.65 3.65 3.67 40000

5.74 5.36 5.8 50000

7.94 7.88 8.01 60000

18.64 18.76 18.71 70000

25.25 25.63 25.41 80000

40.69 40.72 40.71 90000

51.78 52.05 52.81 100000

11
Quick Sort

#include <bits/stdc+
+.h> #include
<fstream> #include
<stdio.h>
using namespace
std; #include
<time.h>
void swap(int* x, int*
y) { int t = *x;
*x = *y;
*y = t;
}
int partition(vector<int>a, int l, int
h) { int pivot = a[h];
int i= (l- 1);
for (int k = l; k <= h - 1; k+
+) { if (a[k] < pivot)
{ k++;
swap(&a[i], &a[k]);
}
}
swap(&a[i + 1],
&a[h]); return (i +
1);
}
void quickSort(vector<int>a, int l, int
h) { if (l < h) {
int p = partition(a, l,
h); quickSort(a, l, p -
1); quickSort(a, p +
1, h);
}
}
int main()
{
clock_t
start,end;
double t;
vector<int>
vec(20000); int i = 0;
FILE *file;
if (file = fopen("file1.txt", "r"))
{
int a;
while (fscanf(file, "%d", &vec[i]) != EOF)
{
if(i>vec.size(
)) break;
i++;
}
12
fclose(file);
int
n=vec.size();
start =clock();
quickSort(vec,0,n-
1); end=clock();
t=((double)(end-start))/CLOCKS_PER_SEC;
cout<<t;
}
return 0;
}
BEST CASE AVERAGE WORST C
CASE

0.53 0.35 1.12 10000

1.6 1.12 2.35 20000

1.82 1.95 2.98 30000

3.65 3.65 3.97 40000

5.74 5.36 5.98 50000

7.94 7.88 9.02 60000

18.64 18.71 19.05 70000

25.25 25.61 26.36 80000

40.69 40.65 42.15 90000

51.78 52.12 56.01 100000

Practical-06
Objective : To find the maximum and minimum numbers in a given array.

Theory : If n is odd then initialize min and max as the first element.
If n is even then initialize min and max as minimum and maximum of the first two elements
respectively.
For the rest of the elements, pick them in pairs and compare
their maximum and minimum with max and min respectively

#include<bits/stdc++.h>
using namespace std;
struct Pair
{
int min;
int max;
};
struct Pair getMinMax(int arr[], int n)
{
13
struct Pair minmax;
int i;
if (n % 2 == 0)
{
if (arr[0] > arr[1])
{
}
else
{
}
i = 2;
}
else
{
minmax.max = arr[0];
minmax.min = arr[1];
minmax.min = arr[0];
minmax.max = arr[1];
minmax.min = arr[0];
minmax.max = arr[0];
i = 1;
}
while (i < n - 1)
{
if (arr[i] > arr[i + 1])
{
if(arr[i] > minmax.max)
minmax.max = arr[i];
if(arr[i + 1] < minmax.min)
minmax.min = arr[i + 1];
}
else
{
}
i += 2;
}
if (arr[i + 1] > minmax.max)
minmax.max = arr[i + 1];
if (arr[i] < minmax.min)
minmax.min = arr[i];
return minmax;
}
int main()
{
int n;
cout<<"Enter the number of element : ";
cin>>n;
cout<<endl<<"Enter the elements : ";
int arr[n];
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
Pair res=getMinMax(arr,n);
cout<<"Minimum Element is : "<<res.min<<endl;
cout<<"Maximum Element is : "<<res.max<<endl;
}

14
Practical-07
Objective : To find the Kth smallest number in a given array .

Theory : Used Priority Queue, and inserted first K elements in the array. Then ,for remaining
,each time we compare it with the top element of the priority queue , if the top element is
greater than the current element then we pop front the priority queue and insert the
current element into the priority queue.
#include<bits/stdc+
+.h> using namespace
std;
int findKthMin(int arr[],int n,int k)
{
priority_queue<int>pq;

for(int i=0;i<k;i++)
{
pq.push(arr[i]);
}
int ans;
for(int i=k;i<n;i++)
{
if(arr[i]<pq.top())
{
pq.pop();
pq.push(arr[i]
);
}
}
return pq.top();
}
int main()
{
int n;
cout<<"Enter the number of element
: "; cin>>n;
cout<<endl<<"Enter the elements
: "; int arr[n];
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
int k;
cout<<"Enter the value of k
: "; cin>>k;
int res=findKthMin(arr,n,k);
cout<<"Kthe = "<<k<<" smallest element is : "<<res<<endl;
}
15
16
Practical-08
Objective : To implement the Prim’s Algorithm to find a Minimum Spanning Tree.
Theory : Prim's Algorithm converts it to a tree such that the sum of all edges of the tree is
minimum. Such a tree is called a Minimum Spanning Tree.
It uses the gíeedy appíoach to find this minimum spanning tíee.
#include<bits/stdc+

+.h> using namespace

std; #define V 6

int selectMinVertex(vector<int> &value, vector<bool>&


setMST){ int minimum = INT_MAX;
int vertex;
for(int i = 0; i < V; i++){
if(setMST[i] == false && value[i] < minimum){
vertex = i;
minimum = value[i];
}
}
return vertex;
}
void printMst(int parent[], int graph[V][V])
{ cout << "Src.\tDest.\tWeight\n";
for(int i = 1; i < V; i++){
cout << i << "\t" << parent[i] << "\t" << graph[i][parent[i]] << "\n";
}
}
void findMST(int graph[V]
[V]){ int parent[V];
vector<int> value(V,
INT_MAX); vector<bool>
setMST(V, false);

parent[0] = -1;
value[0] = 0;

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


int U = selectMinVertex(value,
setMST); setMST[U] = true;

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


if(graph[U][j] != 0 && setMST[j] == false && graph[U][j] < value[j]){
value[j] = graph[U][j];
parent[j] = U;
}
}
}
printMst(parent, graph);
}
int main(){
int graph[V][V] = {
{0, 4, 6, 0, 8, 8},
{4, 0, 6, 3, 4, 8},
{6, 2, 0, 1, 8, 1},
{0, 3, 6, 0, 2, 2},
{0, 4, 4, 2, 0, 3},
{0, 0, 0, 3, 7, 4},
17
};
findMST(graph)
; return 0;
}

Practical-09
Objective : To implement the Kruskal’ s Algorithm to find a Minimum Spanning Tree
Theory : Kruskal’s algorithm to find the minimum cost spanning tree uses the greedy
approach. The Greedy Choice is to pick the smallest weight edge that does not cause a cycle
in the MST constructed so far.
#include<bits/stdc+
+.h> using namespace
std;
class DSU{
int
*parent;
int *rank;
public:
DSU(int n){

parent=new
int[n]; rank=new
int[n]; for(int
i=0;i<n;i++)
{
parent[i]
=i;
rank[i]=0;
}
}
int find(int node){
if(node==parent[node]) return
node;
return parent[node]=find(parent[node]);
}

void Union(int u,int

v){ u=find(u);
v=find(v);
if(u!=v)
{
18
if(rank[u]<rank[v])
{
int
temp=u;
u=v;
v=temp;
}
parent[v]=u;

if(rank[u]==rank[v])
rank[u]++;
}
}
};
class
Edge{ publ
ic:

int u,v,weight;

Edge(int U,int V,int


Weight){ u=U;
v=V;
weight=Weight;
}
};
class
Graph{ publ
ic:

int V, E;
vector<Edge>
edges;
Graph(int v,int
e){ V=v;
E=e;
}
static bool comparator(Edge e1, Edge e2)
{
return e1.weight < e2.weight;
}
void MST_Kruskal(){

int
e=0,i=0,sum=0; DSU
dsu(V);
sort(edges.begin(), edges.end(),
comparator); while(e<V-1)
{
Edge edge=edges[i++];

int
u=dsu.find(edge.u);
int
v=dsu.find(edge.v);
if(u!=v)
{
cout<<"Adding edge "<<edge.u<<" <---> "<<edge.v<<" to MST\n";

sum+=edge.weigh
t; dsu.Union(u,v);
19
e++;
}
}
cout<<"MST has a weight of "<<sum;
}

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


edges.push_back(Edge(u,v,weight));
}
};
int main(){

Graph g(6,9);
g.addEdge(0,1,5);
g.addEdge(0,3,8);
g.addEdge(1,9,3);
g.addEdge(1,4,6);
g.addEdge(2,3,4);
g.addEdge(1,4,4);
g.addEdge(8,4,2);
g.addEdge(4,5,2);
g.addEdge(4,5,2);

g.MST_Kruskal();

return 0;
}

Practical-10
Objective : To implement Matrix Chain Multiplication using Dynamic Programming .
Theory : We will use almost the same approach as Recursive Implementation with the only
change that, we will maintain a 2-D array (say dp) of dimensions
n\times n
n×n all of whose entries initialized with -1 where dp[i][j] stores result for the sub-problem
i..j. So for calculating the answer for the sub-problem i..j firstly we will check if we already
have calculated the answer for it in past, by checking that if dp[i][j]!=-1. So if we already
have calculated the answer for it we need not solve it again instead, we can simply return
dp[i][j]

#include<bits/stdc+
+.h> using namespace
std;

int **dp;
int MatrixChainMultiplication(int mat[],int low, int high){
20
if(low==high)
return 0;

if(dp[low][high]!=-1)
return dp[low]
[high];

dp[low][high]=INT_MAX;
for(int k=low;k<high;k+
+){
int cost=MatrixChainMultiplication(mat, low,
k)+ MatrixChainMultiplication(mat, k+1,
high)+ mat[low-1]*mat[k]*mat[high];
if(cost<dp[low][high])
dp[low][high]=cost;
}
return dp[low][high];
}

int main(){
int mat[]={2, 4, 6, 8, 6};
int n=sizeof(mat)/sizeof(mat[0]);
dp=new int*[n];
for(int i=0;i<n;i+
+){ dp[i]=new
int[n]; for(int
j=0;j<n;j++)
dp[i][j]=-1;
}
cout<<"Minimum number of steps are : ";
cout<<MatrixChainMultiplication(mat, 1, n-1);
return 0;
}

Practical-11
Objective : To implement Longest Common Subsequence Problem using Dynamic
Programming .
Theory : The method of dynamic programming reduces the number of function calls. It
stores the result of each function call so that it can be used in future calls without the need
for redundant calls.The time taken by a dynamic approach is the time taken to fill the table
(ie.
O(mn))

#include <bits/stdc+
+.h> using namespace
std;
void lcsAlgo(char *S1, char *S2, int m, int
n) { int LCS_table[m + 1][n + 1];

for (int i = 0; i <= m; i+


+) { for (int j = 0; j <=
n; j++) { if (i == 0 || j
21
== 0)
LCS_table[i][j] = 0;
else if (S1[i - 1] == S2[j - 1])
LCS_table[i][j] = LCS_table[i - 1][j - 1] + 1;
else
LCS_table[i][j] = max(LCS_table[i - 1][j], LCS_table[i][j - 1]);
}
}
int index = LCS_table[m]
[n]; char lcsAlgo[index +
1]; lcsAlgo[index] = '\0';

int i = m, j = n;
while (i > 0 && j > 0) {
if (S1[i - 1] == S2[j - 1]) {
lcsAlgo[index - 1] = S1[i -
1]; i--;
j--;
index--;
}
else if (LCS_table[i - 1][j] > LCS_table[i][j -
1]) i--;
els
e
j--;
}
cout << "S1 : " << S1 << "\nS2 : " << S2 << "\nLCS: " << lcsAlgo << "\n";
}
int main() {
char S1[] =
"abcdabab"; char S2[]
= "acdbcba"; int m =
strlen(S1);
int n = strlen(S2);
lcsAlgo(S1, S2, m,
n);
}

22
Practical-12
Objective : To do the case study of P , NP , NP Complete , NP Hard Problem.
P Class
The P in the P class stands for Polynomial Time. It is the collection of decision
problems(problems with a “yes” or “no” answer) that can be solved by a deterministic
machine in polynomial time.
Features:

1. The solution to P problems is easy to find.


2. P is often a class of computational problems that are solvable and tractable.
Tractable means that the problems can be solved in theory as well as in practice.
But the problems that can be solved in theory but not in practice are known as
intractable.

This class contains many natural problems like:

1. Calculating the greatest common divisor.


2. Finding a maximum matching.
3. Decision versions of linear programming.

NP Class
The NP in NP class stands for Non-deterministic Polynomial Time. It is the collection of
decision problems that can be solved by a non-deterministic machine in polynomial time.
Features:

1. The solutions of the NP class are hard to find since they are being solved
by a non-deterministic machine but the solutions are easy to verify.
2. Problems of NP can be verified by a Turing machine in polynomial time.

This class contains many problems that one would like to be able to solve effectively:

1. Boolean Satisfiability Problem (SAT).


2. Hamiltonian Path Problem.
3. Graph coloring.
NP-hard class

An NP-hard problem is at least as hard as the hardest problem in NP and it is the class of the
problems such that every problem in NP reduces to NP-hard.

Features:

1. All NP-hard problems are not in NP.


2. It takes a long time to check them. This means if a solution for an NP-hard
problem is given then it takes a long time to check whether it is right or not.
3. A problem A is in NP-hard if, for every problem L in NP, there
exists a polynomial-time reduction from L to A.

Some of the examples of problems in Np-hard are:


23
1. Halting problem.
2. Qualified Boolean formulas.
3. No Hamiltonian cycle.

NP-complete
class

A problem is NP-complete if it is both NP and NP-hard. NP-complete problems are the hard
problems in NP.

Features:

1. NP-complete problems are special as any problem in NP class can be


transformed or reduced into NP-complete problems in polynomial time.
2. If one could solve an NP-complete problem in polynomial time, then one could
also solve any NP problem in polynomial time.
3. Some example problems include:
1. Decision version of 0/1 Knapsack.
2. Hamiltonian Cycle.
3. Satisfiability.
4. Vertex cover.

24

You might also like