NIEIT Ada Lab Manual
NIEIT Ada Lab Manual
Technology
Department of Computer Science & Engg
And
Department of Information science & Engg
ALGORITHMS LABORATORY
th MANUAL
For 5 SEM CSE & ISE
Sub Code: 06CSL58
Introduction
Analysis of algorithms
Analysis is one of the important step in problem solving. Here we estimate time and
space for a given problem. Once we have these estimations, select an algorithm which is more
efficient in terms of time and space.
Space Efficiency: Indicates how much extra memory is required for the algorithm .
The most important characteristics of any algorithm are it’s simplicity and generality.
Simplicity: Simple algorithms are easy to understand, debug and easy to program.
Generality: It should be a generic solution to the given problem.
Design an algorithm
After the problem is clearly stated and the type of algorithm and data structure are
selected, the solution to solve the problem should be specified. One or more algorithms may be
correct to solve a given problem. But effectiveness may be different from solution to solution.
Algorithm
Notion of an algorithm
Linear Search
In computer science, linear search is a search algorithm, also known as sequential
search, that is suitable for searching a list of data for a particular value.
It operates by checking every element of a list one at a time in sequence until a match is
found. Linear search runs in O(n). If the data are distributed randomly, the expected number of
comparisons that will be necessary is: where n is the number of elements in the list and k is the
number of times that the value being searched for appears in the list. The best case is that the
value is equal to the first element tested, in which case only 1 comparison is needed. The worst
case is that the value is not in the list (or it appears only once at the end of the list), in which case
n comparisons are needed.
The simplicity of the linear search means that if just a few elements are to be searched it
is less trouble than more complex methods that require preparation such as sorting the list to be
searched or more complex data structures, especially when entries may be subject to frequent
revision. Another possibility is when certain values are much more likely to be searched for than
others and it can be arranged that such values will be amongst the first considered in the list.
Binary search is a technique for locating a particular value in a sorted list. The method
makes progressively better guesses, and closes in on the location of the sought value by selecting
the middle element in the span (which, because the list is in sorted order, is the median value),
comparing its value to the target value, and determining if it is greater than, less than, or equal to
the target value. A guessed index whose value turns out to be too high becomes the new upper
bound of the span, and if its value is too low that index becomes the new lower bound. A binary
search is an example of a divide and conquer search algorithm.
• Implement Recursive Binary search and Linear search and 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.
Heap Sort
• Sort a given set of elements using the Heap sort method 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.
#include<iostream.h>
#include<conio.h>
//#define MTIMES 100
//#define NTIMES 10000
#include<time.h>
#include<dos.h>
#include<stdlib.h>
int i,n,a[25000],j;
class heap
{
public: void heapify(int a[], int n);
void heapsort(int a[],int n);
};
void main()
{
st=clock();
// for(i=0;i<MTIMES;i++)
//for(j=0;j<NTIMES;j++)
h.heapsort(a,n);
et=clock();
cout<<"\nBegin time="<<st<<endl;
cout<<"End time="<<et<<endl;
cout<<"Total number of clock ticks="<<(et-st)<<endl;
cout<<"Total time required="<<(et-st)/CLK_TCK<<endl;
getch();
}
Merge sort
• Divide the unsorted list into two sublists of about half the size.
• A small list will take fewer steps to sort than a large list.
• Fewer steps are required to construct a sorted list from two sorted lists than two unsorted
lists. For example, you only have to traverse each list once if they're already sorted (see
the merge function below for an example implementation).
#include<iostream.h>
#include<conio.h>
#include<dos.h>
#include<time.h>
int a[1000],b[1000],c[1000],i,n;
class msort
{
int mid;
if(l<h)
{
mid=(l+h)/2;
delay(100);
mergesort(l,mid);
mergesort(mid+1,h);
merge(l,h,mid);
}
}
void main()
{
clock_t st,et;
msort m;
clrscr();
cout<<"\nBegin time="<<st<<endl;
cout<<"End time="<<et<<endl;
cout<<"Total number of clock ticks="<<(et-st)<<endl;
cout<<"Total time required="<<(et-st)/CLK_TCK<<endl;
getch();
}
Selection sort
Selection sort is a sorting algorithm, specifically an in-place comparison sort. It has O(n2)
complexity, making it inefficient on large lists, and generally performs worse than the similar
insertion sort. Selection sort is noted for its simplicity, and also has performance advantages over
more complicated algorithms in certain situations.
• Repeat the steps above for the remainder of the list (starting at the second position and
advancing each time)
Effectively, we divide the list into two parts: the sublist of items already sorted, which we build
up from left to right and is found at the beginning, and the sublist of items remaining to be
sorted, occupying the remainder of the array.
• a Sort a given set of elements using Selection sort and determine the
time required to sort 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.
#include<iostream.h>
#include<conio.h>
#include<dos.h>
#include<time.h>
#include<stdlib.h>
int a[16000],i,n,j,min,t;
class selsort
{
public: void selection(int);
};
for(j=i+1;j<n;j++)
{
if(a[j]<a[min])
min=j;
}
t=a[i];
a[i]=a[min];
a[min]=t;
}
}
void main()
{
clock_t st,et;
selsort s;
clrscr();
for(i=0;i<n;i++)
cout<<"\t"<<a[i];
st=clock();
s.selection(n);
et=clock();
cout<<"\nThe sorted array is"<<endl;
for(i=0;i<n;i++)
cout<<"\t"<<a[i];
cout<<"\nBegin time="<<st<<endl;
cout<<"End time="<<et<<endl;
cout<<"Total number of clock ticks="<<(et-st)<<endl;
cout<<"Total time required="<<(et-st)/CLK_TCK<<endl;
getch();
}
The knapsack problem or rucksack problem
The knap sack 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 a given limit and the total value is as large as possible. It derives
its name from the problem faced by someone who is constrained by a fixed-size knapsack and
must fill it with the most useful items.
The problem often arises in resource allocation with financial constraints. A similar
problem also appears in combinatorics, complexity theory, cryptography and applied
mathematics.
A dynamic programming solution for the 0-1 knapsack problem also runs in pseudo-
polynomial time. Assume w1, ..., wn, W are strictly positive integers. Define A(j, Y) to be the
maximum value that can be attained with weight less than or equal to Y using items up to j.
• A(0, Y) = 0
• A(j, 0) = 0
The solution can then be found by calculating A(n, W). To do this efficiently we can use a table
to store previous computations. This solution will therefore run in O(nW) time and O(nW) space,
though with some slight modifications we can reduce the space complexity to O(W).
int n,m,i,j,a,b,w[10],v[10][10],p[10];
class knap
{
public: int max(int a,int b);
void ksack(int n,int w[],int m,int v[][10],int p[]);
void optsol(int n,int m,int w[],int v[10][10]);
};
i=n; j=m;
while(i!=0 && j!=0)
{
if(v[i][j]!=v[i-1][j])
{
x[i]=1;
j=j-w[i];
}
i=i-1;
}
cout<<"\nThe Object Selected is:\n";
for(i=1;i<=n;i++)
{
cout<<"X["<<i<<"]"<<"\t";
}
cout<<"=";
for(i=1;i<=n;i++)
{
cout<<x[i];
}
}
void main()
{
knap k;
clrscr();
cout<<"Enter the number of objects\n";
cin>>n;
cout<<"\nEnter the weights of n objects\n";
for(i=1;i<=n;i++)
cin>>w[i];
cout<<"\nEnter the profits of n objects\n";
for(i=1;i<=n;i++)
cin>>p[i];
cout<<"\nEnter the capacity of knapsack\n";
cin>>m;
k.ksack(n,w,m,v,p);
k.optsol(n,m,w,v);
getch();
}
Dijkstra's algorithm,
For a given source vertex (node) in the graph, the algorithm finds the path with lowest
cost (i.e. the shortest path) between that vertex and every other vertex. It can also be used for
finding costs of shortest paths from a single vertex to a single destination vertex by stopping the
algorithm once the shortest path to the destination vertex has been determined. For example, if
the vertices of the graph represent cities and edge path costs represent driving distances between
pairs of cities connected by a direct road, Dijkstra's algorithm can be used to find the shortest
route between one city and all other cities. As a result, the shortest path first is widely used in
network routing protocols, most notably (Intermediate system to intermediate system (IS-IS),
and OSPF (Open Shortest Path First).
• From a given vertex in a weighted connected graph, find shortest
paths to other vertices using Dijkstra's algorithm
#include<iostream.h>
#include<conio.h>
int i,j,count=1,source,curr,cost[10][10];
int visit[100],d[100],n;
class dijstra
{
public: void read();
int min(int a,int b);
int getcur();
void SSPT();
};
int dijstra::getcur()
{
int i=1,curr;
while(visit[i]==1)
i++;
curr=i;
for(i=curr+1;i<=n;i++)
if(d[i]<d[curr] && visit[i]==0)
curr=i;
return curr;
}
void dijstra::read()
{
cout<<"\n Enter the number of nodes:";
cin>>n;
cout<<"\n Enter the cost matrix:\n";
cout<<"\nEnter 0->diagonal elements and 99->No direct edge cost\n";
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
cin>>cost[i][j];
visit[i]=0;
}
}
cout<<"\n Enter the source vertex:\n";
cin>>source;
visit[source]=1;
}
void dijstra::SSPT()
{
for(i=1;i<=n;i++)
d[i]=cost[source][i];
while(count<n)
{
curr=getcur();
visit[curr]=1;
count++;
for(i=1;i<=n;i++)
if(visit[i]==0)
{
d[i]=min(d[i],d[curr]+cost[curr][i]);
}
}
cout<<"\n PATH DISTANCE\n";
for(i=1;i<=n;i++)
cout<<"\n("<<source<<","<<i<<")"<<"--->"<<d[i];
}
void main()
{
dijstra d;
clrscr();
d.read();
d.SSPT();
getch();
}
/*--------------------------------------------------------------------
output:
Quick Sort
Quicksort is a well-known sorting algorithm developed by C. A. R. Hoare that, on
average, makes Θ(nlogn) (big O notation) comparisons to sort n items. However, in the worst
case, it makes Θ(n2) comparisons. Typically, quicksort is significantly faster in practice than
other Θ(nlogn) algorithms, because its inner loop can be efficiently implemented on most
architectures, and in most real-world data, it is possible to make design choices which minimize
the probability of requiring quadratic time.
• Reorder the list so that all elements which are less than the pivot come before the pivot
and so that all elements greater than the pivot come after it (equal values can go either
way). After this partitioning, the pivot is in its final position. This is called the partition
operation.
• Recursively sort the sub-list of lesser elements and the sub-list of greater elements.
The base case of the recursion are lists of size zero or one, which are always sorted. In simple
pseudocode, the algorithm might be expressed as this:
function quicksort(array)
var list less, greater
if length(array) ≤ 1
return array
select and remove a pivot value pivot from array
for each x in array
if x ≤ pivot then append x to less
else append x to greater
return concatenate(quicksort(less), pivot, quicksort(greater))
• Sort a given set of elements using Quick sort method and determine
the time required 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.
#include<iostream.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
class quicksort
{
int n,a[1000];
int partition(int,int);
void swap(int,int);
public:
void qsort(int,int);
void getarray();
void putarray();
quicksort(int i)
{ n=i;
}
};
int quicksort::partition(int low,int high)
{
int p,i,j;
p=i=low;
j=high+1;
while(i<=j)
{ do
i++;
while(a[i]<a[p]);
do
j--;
while(a[j]>a[p]);
if(i<j)
swap(i,j);
}
swap(p,j);
return j;
}
void quicksort::getarray()
{
for(int i=0;i<n;i++)
cin>>a[i];
}
void quicksort::putarray()
{
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
}
void main()
{
int n;
clock_t s,e;
clrscr();
cout<<"\nEnter the no. of elements:\n ";
cin>>n;
s=clock();
quicksort a1(n);
cout<<"\nEnter the elements of the array:\n";
a1.getarray();
cout<<"\nEntered elements of the array:\n";
a1.putarray();
cout<<"\nThe sorted array is:\n";
a1.qsort(0,n-1);
e=clock();
a1.putarray();
cout<<"\nTime taken for sort\n"<<(e-s)/CLK_TCK;
getch();
}
Kruskal’s Algorithm
Kruskal's algorithm is an algorithm in graph theory that finds a minimum spanning tree for a
connected weighted graph. This means it finds a subset of the edges that forms a tree that
includes every vertex, where the total weight of all the edges in the tree is minimized. If the
graph is not connected, then it finds a minimum spanning forest (a minimum spanning tree for
each connected component). Kruskal's algorithm is an example of a greedy algorithm. This
algorithm first appeared in Proceedings of the American Mathematical Society, pp. 48–50 in
1956, and was written by Joseph Kruskal
It works as follows:
• create a forest F (a set of trees), where each vertex in the graph is a separate tree
• create a set S containing all the edges in the graph
• while S is nonempty
• if that edge connects two different trees, then add it to the forest, combining two
trees into a single tree
At the termination of the algorithm, the forest has only one component and forms a minimum
spanning tree of the graph.
#include<iostream.h>
#include<conio.h>
int cost[10][10],root[10],min,edge=1,mincost=0;
int i,j,a,b,u,v,n;
class MCST
{
public: void kruskal();
};
void MCST::kruskal()
{
cout<<"Spanning Trees is:\n";
while(edge<n)
{
for(i=1,min=999;i<=n;i++)
for(j=1;j<=n;j++)
if(cost[i][j]<min)
{
min=cost[i][j];
a=u=i;
b=v=j;
}
while(root[u])
u=root[u];
while(root[v])
v=root[v];
if(u!=v)
{
edge++;
cout<<"\n"<<"("<<a<<","<<b<<")"<<"="<<min;
mincost+=min;
root[v]=u;
}
cost[a][b]=cost[b][a]=999;
}
cout<<"\n Minimum cost = "<<mincost;
}
void main()
{
MCST k;
clrscr();
cout<<"\n Enter the number of vertices:";
cin>>n;
cout<<"\n Enter the cost matrix";
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cin>>cost[i][j];
if(cost[i][j]==0)
cost[i][j]=999;
}
k.kruskal();
getch();
}
Algorithm (informal)
• Enqueue the root node.
• If the element sought is found in this node, quit the search and return a result.
• Otherwise enqueue any successors (the direct child nodes) that have not yet been
examined.
• If the queue is empty, every node on the graph has been examined – quit the search and
return "not found".
Note: Using a stack instead of a queue would turn this algorithm into a depth-first search. (DFS)
Applications
Breadth-first search can be used to solve many problems in graph theory, for example:
• Finding the shortest path between two nodes u and v (in an unweighted graph)
• Finding the shortest path between two nodes u and v (in a weighted graph: see talk page)
#include<iostream.h>
#include<conio.h>
int i,j,n,f=0,r=-1,source;
int v,cost[10][10],q[10],q1[10];
class reach
{
public: void bfs(int u);
void read();
};
void reach::bfs(int u)
{
for(v=1;v<=n;v++)
{
if(cost[u][v]==1&&q1[v]==0)
q[++r]=v;
}
if(f<=r)
{
q1[q[f]]=1;
bfs(q[f++]);
}
}
void reach::read()
{
cout<<"Enter the number of vertices\n";
cin>>n;
cout<<"Enter the cost adjacency matrix\n";
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>cost[i][j];
for(i=1;i<=n;i++)
{
q[i]=0;
q1[i]=0;
}
cout<<"Enter the source vertex\n";
cin>>source;
bfs(source);
cout<<"The vertices from :"<<source<<"\n\n";
for(i=1;i<=n;i++)
{
if(q1[i]==1)
cout<<i<<"\tis reachable\n";
}
}
void main()
{
reach r;
clrscr();
r.read();
getch();
}
Depth-first search (DFS)
Depth First Search is an algorithm for traversing or searching a tree, tree structure, or
graph. One starts at the root (selecting some node as the root in the graph case) and explores as
far as possible along each branch before backtracking.
Applications
Algorithms where DFS is used:
int n,j,source,cost[10][10],s[10],i,connected,flag;
class graph
{
public: void dfs(int n,int u,int cost[10][10],int s[10]);
void read();
};
void graph::read()
{
cout<<"Enter the number of vertices\n";
cin>>n;
cout<<"Enter the cost matrix\n";
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>cost[i][j];
connected=0;
for(j=1;j<=n;j++)
{
for(i=1;i<=n;i++)
s[i]=0;
dfs(n,j,cost,s);
flag=0;
for(i=1;i<=n;i++)
if(s[i]==0)
flag=1;
if(flag==0)
connected=1;
}
if(connected==1)
cout<<"The graph is connected\n";
else
cout<<"the graph is not connected\n";
}
void main()
{
graph g;
clrscr();
g.read();
getch();
}
Subset construction
Backtracking is a refinement of the brute force approach, which systematically searches
for a solution to a problem among all available options. It does so by assuming that the solutions
are represented by vectors (v1, ..., vm) of values and by traversing, in a depth first manner, the
domains of the vectors until the solutions are found.
The objective of this problem is to find as many subsets as possible whose individual sum
equals some constant value.
• Find a subset of a given set S = {sl,s2,.....,sn} of n positive
integers whose sum is equal to a given positive integer d. For
example, if S= {1, 2, 5, 6, 8} and d = 9 there are two
solutions{1,2,6}and{1,8}.A suitable message is to be displayed if
the given problem instance doesn't have a solution.
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
void set::read()
{
cout<<"\n Enter the number of elements:\n";
cin>>n;
cout<<"\n Enter the elements in ascending order:";
for(i=0;i<n;i++)
{
cout<<"\n\t:";
cin>>s[i];
}
cout<<"\n Enter the sum:";
cin>>d;
for(i=0;i<n;i++)
r+=s[i];
subset(0,0,r);
if(!flag)
cout<<"Solution doesnot exist:\n";
void main()
{
set s;
clrscr();
s.read();
getch();
}
******************************************************************************
*
/* OUTPUT
Enter the number of elements:4
:5
:6
:7
Subset 1: 3 5 7
*/
******************************************************************************
*
#include<iostream.h>
#include<conio.h>
#include<string.h>
#include<stdio.h>
int table[256],flag;
char t[100],p[100];
class horse
{
public: void shift_table(char p[],int m);
int horspool(char t[],char p[]);
void read();
};
void horse::read()
{
cout<<"\n Enter the text:\n\t";
gets(t);
cout<<"\n Enter the pattern:\n\t";
gets(p);
flag=horspool(t,p);
if(flag==-1)
cout<<"\n Pattern string not found";
else
cout<<"\n Pattern string found at position= "<<flag+1<<"\n";
getch();
}
void main()
{
clrscr();
horse h;
h.read();
}
******************************************************************************
/* OUTPUT
Run 1:
Enter the text:
ferrari rules
Run 2:
Enter the text:
jim_saw_me_in_the_barber_shop
Binomial coefficient
The Binomial coefficients C(n, k) is the number of ways of choosing a subset of k
elements from a set of n elements. It arises in probability and statistics, e.g., the
probability of flipping a biased coin (with probability p of heads) n times and getting
exactly k heads is C(n, k) pk (1-p)k. One formula for computing binomial coefficients is
C(n, k) = n! / (k! (n-k)!). This formula is not so amenable to direct computation because
the intermediate results may overflow, even if the final answer does not. For example
C(100, 15) = 253338471349988640 fits in a 64-bit long, but the binary representation
of 100! is 525 bits long. Pascal's identity expresses C(n, k) in terms of smaller binomial
coefficients:
#include<iostream.h>
#include<conio.h>
int c[20][20],n,k;
class bino
{
public: int min(int a,int b);
void binomial(int n,int k);
void bino::read();
};
void bino::read()
{
cout<<"\n Enter n:";
cin>>n;
cout<<"\n Enter k:";
cin>>k;
if(k<0 || n<0 || n<k)
cout<<"\n Invalid entry";
else
binomial(n,k);
getch();
}
void main()
{
clrscr();
bino b;
b.read();
}
******************************************************************************
*
/* OUTPUT
RUN 1:
Enter n:5
Enter k:3
RUN 2:
Enter n:3
Enter k:7
Invalid entry
*/
******************************************************************************
*
Prim’s Algorithm
Prim's algorithm is an algorithm in graph theory that finds a minimum spanning tree for
a connected weighted graph. This means it finds a subset of the edges that forms a tree that
includes every vertex, where the total weight of all the edges in the tree is minimized. The
algorithm was developed in 1930 by Czech mathematician Vojtěch Jarník and later
independently by computer scientist Robert C. Prim in 1957 and rediscovered by Edsger Dijkstra
in 1959. Therefore it is sometimes called the DJP algorithm, the Jarník algorithm, or the
Prim-Jarník algorithm.
The algorithm continuously increases the size of a tree starting with a single vertex until it spans
all the vertices.
• Initialize: Vnew = {x}, where x is an arbitrary node (starting point) from V, Enew = {}
• Choose edge (u,v) with minimal weight such that u is in V new and v is not (if there
are multiple edges with the same weight, choose arbitrarily but consistently)
int i,j,count=1,source,curr,cost[10][10],r[10],s[10],sum=0;
int visit[100],d[100],n;
class prims
{
public: void read();
int min(int a,int b);
int getcur();
void MCST();
};
int prims::min(int a,int b)
{
if(a<=b)
return a;
else
return b;
int prims::getcur()
{
int i=1,curr;
while(visit[i]==1)
i++;
curr=i;
for(i=curr+1;i<=n;i++)
if(d[i]<d[curr] && visit[i]==0)
curr=i;
return curr;
}
void prims::read()
{
cout<<"\n Enter the number of nodes:";
cin>>n;
cout<<"\n Enter the cost matrix:\n";
cout<<"\nEnter 0->diagonal elements and 99->No direct edge cost\n";
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
cin>>cost[i][j];
visit[i]=0;
}
}
}
void prims::MCST()
{
for(i=1;i<=n;i++)
{
d[i]=cost[1][i];
r[i]=1;
}
visit[1]=1;
while(count<n)
{
curr=getcur();
visit[curr]=1;
count++;
for(i=1;i<=n;i++)
if(visit[i]==0)
{
s[i]=d[i];
d[i]=min(d[i],cost[curr][i]);
if(d[i]!=s[i])
r[i]=curr;
}
}
cout<<"\n EDGES WEIGHTS\n";
for(i=1;i<=n;i++)
cout<<"\n("<<r[i]<<","<<i<<")"<<"--->"<<d[i];
cout<<"\nThe minimum cost spanning tree is\t";
for(i=1;i<=n;i++)
sum=sum+d[i];
cout<<sum;
}
void main()
{
prims p;
clrscr();
p.read();
p.MCST();
getch();
}
/*--------------------------------------------------------------------
output:
EDGES WEIGHTS
(1,1)---------> 0
(1,2)---------> 1
(1,3)---------> 3
(3,4)---------> 2
(1,5)---------> 5
Warshall’s Algorithm
Warshall's algorithm enables to compute the transitive closure of the adjacency matrix
of any digraph. The transitive closure of a digraph G=(V,E) with set of vertices and
edges is defined as Boolean matrix (only 0’s and 1’s ) of size n X n. Such that
a[i,,j]= 1 if there is a non trival directed path
else a[i,j]=0
Here input is an digraph it should be supplied as an adjucancy matrix.
#include<iostream.h>
#include<conio.h>
int i,j,k,n,a[10][10],p[10][10],flag=1;
class tclose
{
public: void warshall(int n, int a[10][10], int p[10][10]);
void read(int n, int a[10][10]);
void write(int n, int a[10][10]);
};
for(k=0;k<n;k++)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if((p[i][k]==1 && p[k][j]==1))
p[i][j]=1;
}
void main()
{
tclose t;
clrscr();
cout<<"\n enter the no. of nodes:";
cin>>n;
cout<<"enter the adjacent matrix:";
t.read(n,a);
t.warshall(n,a,p);
cout<<"The Transitive closure(path matrix)\n";
t.write(n,p);
getch();
}
******************************************************************************
*
/* -----OUTPUT-----
1 1 1 1
1 1 1 1
0 0 0 0
1 1 1 1
*/
******************************************************************************
*
13 b. Implement Floyds algorithm for the all pairs Shortest path problem.
#include<iostream.h>
#include<conio.h>
int i,j,k,n;
int cost[10][10],d[10][10];
class floy
{
public: int min(int a , int b);
void floyd(int n, int cost[10][10], int d[10][10]);
void read(int n, int a[10][10]);
void write(int n, int a[10][10]);
};
for(k=0;k<n;k++)
{
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
}
}
}
void main()
{
clrscr();
floy f;
cout<<"Enter the number of nodes:\n";
cin>>n;
cout<<"\nEnter the cost adjacency matrix:\n";
cout<<"Enter0->Self loop 99->No direct Edge cost:\n\n";
f.read(n,cost);
f.floyd(n,cost,d);
cout<<"\nSolution to all pairs shortest path problem is:\n";
f.write(n,d);
getch();
}
******************************************************************************
*
/* -----OUTPUT-----
Enter the no of nodes : 4
0 10 3 4
2 0 5 6
7 7 0 1
6 16 9 0
*/
******************************************************************************
*
N Queen Problem
The n-queens problem consists in placing n non-attacking queens on an n-by-n chess
board. A queen can attack another queen vertically, horizontally, or diagonally. E.g.
placing a queen on a central square of the board blocks the row and column where it is
placed, as well as the two diagonals (rising and falling) at whose intersection the queen
was placed. The algorithm to solve this problem uses backtracking, but we will unroll
the recursion. The basic idea is to place queens column by column, starting at the left.
New queens must not be attacked by the ones to the left that have already been placed
on the board. We place another queen in the next column if a consistent position is
found. All rows in the current column are checked. We have found a solution if we
placed a queen in the rightmost column.
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
Solution: 1
* * Q *
Q * * *
* * * Q
* Q * *
Solution: 2
* Q * *
* * * Q
Q * * *
* * Q *
Total no of solutions = 2*/
• Define backtracking