0% found this document useful (0 votes)
476 views

Daa Lab Manual Kcs553 2022-23

The document provides details about the Heapsort algorithm including: 1. Heapsort combines attributes of merge sort and insertion sort, running in O(n log n) time like merge sort but sorting in place like insertion sort. 2. It uses a heap data structure to manage information during sorting. Common heap operations like MaxHeapify and BuildMaxHeap are used. 3. The algorithm builds a max heap from the input data, places the largest item at the root, replaces it with the last item and reduces the heap size, repeating until the heap size is 1.

Uploaded by

2030195
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)
476 views

Daa Lab Manual Kcs553 2022-23

The document provides details about the Heapsort algorithm including: 1. Heapsort combines attributes of merge sort and insertion sort, running in O(n log n) time like merge sort but sorting in place like insertion sort. 2. It uses a heap data structure to manage information during sorting. Common heap operations like MaxHeapify and BuildMaxHeap are used. 3. The algorithm builds a max heap from the input data, places the largest item at the root, replaces it with the last item and reduces the heap size, repeating until the heap size is 1.

Uploaded by

2030195
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/ 89

DAA LAB PROGRAMS

DEPARTMENT OF COMPUTER SCIENCE DAA


Lab [KCS 553]
PRACTICAL
LIST

SESSION: 2022-23 SEMESTER-ODD

FACULTY NAME:

S.NO PRACTICAL

1 Program for Recursive Binary & Linear Search.

2 Program for Heap Sort.


3 Program for Merge Sort.
4 Program for Selection Sort.
5 Program for Insertion Sort.
6 Program for Quick Sort.
7 Knapsack Problem using Greedy Solution

8 Perform Travelling Salesman Problem

9 Find Minimum Spanning Tree using Kruskal’s Algorithm

10 Implement N Queen Problem using Backtracking

11 Sort a given set of n integer elements using Quick Sort method and compute its time
complexity. Run the program for varied values of n> 5000 and record the time taken
to sort. Plot a graph of the time taken versus non graph sheet. The elements can be
read from a file or can be generated using the random number generator.
Demonstrate using Java how the divide and- conquer method works along with its
time complexity analysis: worst case, average case and best case.
12 Sort a given set of n integer elements using Merge Sort method and compute its time
complexity. Run the program for varied values of n> 5000, and record the time taken
to sort. Plot a graph of the time taken versus non graph sheet. The elements can be
read from a file or can be generated using the random number generator.
Demonstrate how the divide and- conquer method works along with its time
complexity analysis: worst case, average case and best case.
13 Implement the 0/1 Knapsack problem using
(a) Dynamic Programming method (b) Greedy method

2
14 From a given vertex in a weighted connected graph, find shortest paths to other
vertices using Dijkstra's algorithm.
15 Find Minimum Cost Spanning Tree of a given connected undirected graph using
Kruskal's algorithm. Use Union-Find algorithms in your program.
16 Find Minimum Cost Spanning Tree of a given undirected graph using Prim’s
Algorithm
17 Write programs to (a) Implement All-Pairs Shortest Paths problem using Floyd's
algorithm. (b) Implement Travelling Salesperson problem using Dynamic
programming.
18 Design and implement to 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}. Display a suitable
message if the given problem instance doesn't have a solution.
19 Design and implement to find all Hamiltonian Cycles in a connected undirected
Graph G of n vertices using backtracking principle.

3
1. RECURSIVE BINARY & LINEAR SEARCH
A linear search scans one item at a time, without jumping to any item.
 The worst-case complexity is O(n), sometimes known an O(n) search
 Time taken to search elements keep increasing as the number of elements are increased.

A binary search however, cut down your search to half as soon as you find middle of a sorted
list.
 The middle element is looked to check if it is greater than or less than the value to be
searched.
 Accordingly, search is done to either half of the given list

Important Differences
 Input data needs to be sorted in Binary Search and not in Linear Search
 Linear search does the sequential access whereas Binary search access data randomly.
 Time complexity of linear search is O(n) & Binary search has time complexity O(log n).
 Linear search performs equality comparisons and Binary search performs ordering
comparisons

ALGORITHM

Linear Search (Array A, Value x)


1. Set i to 1
2. if i > n then go to step 7
3. if A[i] = x then go to step 6
4. Set i to i + 1
5. Go to Step 2
6. Print Element x Found at index i and go to step 8
7. Print element not found
8. Exit

Binary Search (Array A, Value x)


1. Start with the middle element:
a. If the target value is equal to the middle element of the array, then return the
index of the middle element.
b. If not, then compare the middle element with the target value,
i. If the target value is greater than the number in the middle index, then pick
the elements to the right of the middle index and start with Step 1.
ii. If the target value is less than the number in the middle index, then pick
the elements to the left of the middle index and start with Step 1.
2. When a match is found, return the index of the element matched.
3. If no match is found, then return -1

4
PSEUDO-CODE

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

Procedure binary_search
A ← sorted array
n ← size of array
x ← value to be searched

Set lowerBound =
1 Set upperBound
=n

while x not found


if upperBound < lowerBound
EXIT: x does not exist.

set midPoint = lowerBound + ( upperBound - lowerBound ) / 2

if A[midPoint] < x
set lowerBound = midPoint + 1

if A[midPoint] > x
set upperBound = midPoint - 1

if A[midPoint] = x
EXIT: x found at location midPoint
end while

end procedure

PROGRAM

#include <stdio.h>
#define MAX_LEN
5
10

void l_search_recursive(int l[],int num,int ele);

6
void b_search_recursive(int l[],int num,int ele);
void read_list(int l[],int num);
void print_list(int l[],int num);

void main ( )
{
int l[MAX_LEN], num, ele;
int ch;

clrscr();

printf("======================================================");
printf("\n\t\t\tMENU");
printf("\n=====================================================");
printf("\n[1] Linary Search");
printf("\n[2] Binary Search");
printf("\n\nEnter your
Choice:"); scanf("%d",&ch);

if(ch<=2 & ch>0)


{
printf("Enter the number of elements
:"); scanf("%d",&num);
read_list(l,num);
printf("\nElements present in the list are:\n\n");
print_list(l,num);
printf("\n\nElement you want to search:\n\n");
scanf("%d",&ele);

switch(ch)
{
case 1:printf("\n**Linear Search**\n");
l_search_recursive(l,num,ele);
getch();
break;

case 2:printf("\n**Binary Search**\n");


b_search_recursive(l,num,ele);
getch();

7
break;
}
}
getch();
}
/*end main*/

/* Recursive Linear Search Method*/


void l_search_recursive(int l[],int num,int ele)
{
int f = 0;

if( l[num] == ele)


{
printf("\nThe element %d is present at position %d in list\
n",ele,num); f=1;
}
else
{
if((num==0) && (f==0))
{
printf("The element %d is not found.",ele);
}
else
{
l_search(l,num-1,ele);
}
}
getch();
}

/* Recursive Binary Search Method*/


int b_search_recursive(int l[],int arrayStart,int arrayEnd,int a)
{
int m,pos;
if (arrayStart<=arrayEnd)
{
m=(arrayStart+arrayEnd)/2;
if (l[m]==a)
8
return m;
else if (a<l[m])
return b_search_recursive(l,arrayStart,m-1,a);
else
return b_search_recursive(l,m+1,arrayEnd,a);
}
return -1;
}

9
2. HEAPSORT
Combines the better attributes of merge sort and insertion sort.
Like merge sort, but unlike insertion sort, running time is O(n lg
n). Like insertion sort, but unlike merge sort, sorts in place.
Introduces an algorithm design technique
Create data structure (heap) to manage information during the execution of an
algorithm. The heap has other applications beside sorting- Priority Queues.

Heap Procedures for Sorting


 MaxHeapify O(lg n)
 BuildMaxHeap O(n)
 HeapSort O(n lg n)

Example

ALGORITHM

1. Build a max heap from the input data.


2. At this point, the largest item is stored at the root of the heap. Replace it with the last item
of the heap followed by reducing the size of heap by 1. Finally, heapify the root of tree.

10
3. Repeat above steps while size of heap is greater than 1.

PSEUDO-CODE

MaxHeapify(A, i)
1. l  left(i)
2. r  right(i)
3. if l  heap-size[A] and A[l] > A[i]
4. then largest  l
5. else largest  i
6. if r  heap-size[A] and A[r] > A[largest]
7. then largest  r
8. if largest i
9. then exchange A[i]  A[largest]
10. MaxHeapify(A, largest)

BuildMaxHeap(A)
1. heap-size[A]  length[A]
2. for i  length[A]/2 downto 1
3. do MaxHeapify(A, i)

HeapSort(A)
1. Build-Max-Heap(A)
2. for i  length[A] downto 2
3. do exchange A[1]  A[i]
4. heap-size[A]  heap-size[A] – 1
5. MaxHeapify(A, 1)

PROGRAM

#include<stdio.h>
#include<conio.h>
void max_heapify(int *,int);
void build_max_heap(int

11
*,int);

12
void heapsort(int *,int);
void swap(int,int);
int heapsize;
int main()
{
int *arr,n,i;
printf("Enter no. of elements = ");
scanf("%d",&n);
arr=(int *)malloc(sizeof(int)*n);
for(i=0;i<n;i++)
{
printf("Enter array elements =
"); scanf("%d",&arr[i]);
}
//heapsize = n;
heapsort(arr,n); printf("\
nAfter heapsort \n");
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
void heapsort(int *arr,int len)
{
int i;
build_max_heap(arr,len);
for(i= len-1;i>=1;i--)
{
swap(&arr[0],&arr[i]);
heapsize = heapsize -1;
max_heapify(arr,0);
}
}
void max_heapify(int *arr,int i)
{
int l=2*i,r=2*i+1,largest;
if(l<heapsize &&
arr[l]>arr[i])

13
largest = l;

14
else
largest = i;
if(r<heapsize &&
arr[r]>arr[largest]) largest = r;

if(largest != i)
{
swap(&arr[i],&arr[largest]);
max_heapify(arr,largest);
}
}
void build_max_heap(int *arr,int len)
{
heapsize =
len; int i;
for(i =len/2;i>=0;i--)
{
max_heapify(arr,i);
}
}
void swap(int *a ,int *b)
{
int temp = *a;
*a= *b;
*b= temp;
}

15
3. MERGE SORT

Conceptually, a merge sort works as follows:

1. Divide the unsorted list into n sublists, each containing 1 element (a list of 1 element
is considered sorted).
2. Repeatedly merge sublists to produce new sorted sublists until there is only 1
sublist remaining. This will be the sorted list.

Example:

ALGORITHM:

If it is only one element in the list it is already sorted, return.


Divide the list recursively into two halves until it can no more be
divided. Merge the smaller lists into new list in sorted order.

PSEUDO-CODE

procedure mergesort( var a as array


) if ( n == 1 ) return a

16
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

procedure merge( var a as array, var b as array

) var c as array
while ( a and b have elements )
if ( a[0] > b[0] )
add b[0] to the end of c
remove b[0] from b
else
add a[0] to the end of
c remove a[0] from a
end if
end while

while ( a has elements )


add a[0] to the end of
c remove a[0] from a
end while

while ( b has elements )


add b[0] to the end of c
remove b[0] from b
end while

return c

end procedure

PROGRAM

17
#include <iostream>

18
using namespace
std; #include
<conio.h>
void merge(int *,int, int , int );
void mergesort(int *a, int low, int high)
{
int mid;
if (low < high)
{
mid=(low+high)/2;
mergesort(a,low,mid);
mergesort(a,mid+1,high);
merge(a,low,high,mid);
}
return;
}
void merge(int *a, int low, int high, int mid)
{
int i, j, k,
c[50]; i = low;
k = low;
j = mid + 1;
while (i <= mid && j <= high)
{
if (a[i] < a[j])
{
c[k] = a[i];
k++;
i++;
}
else
{
c[k] = a[j];
k++;
j++;
}
}
while (i <= mid)
{
c[k] = a[i];
k++;
i++;
}
while (j <= high)
{
19
c[k] = a[j];

20
k++;
j++;
}
for (i = low; i < k; i++)
{
a[i] = c[i];
}
}

int main()
{
int a[20], i, b[20];
cout<<"enter the elements\
n"; for (i = 0; i < 5; i++)
{
cin>>a[i];
}
mergesort(a, 0, 4);
cout<<"sorted array\n";
for (i = 0; i < 5; i++)
{
cout<<a[i];
}
cout<<"enter the elements\
n"; for (i = 0; i < 5; i++)
{
cin>>b[i];
}
mergesort(b, 0, 4);
cout<<"sorted array\n";
for (i = 0; i < 5; i++)
{
cout<<b[i];
}
getch();
}

21
4. SELECTION SORT
The selection sort algorithm sorts an array by repeatedly finding the minimum element
considering ascending order) from unsorted part and putting it at the beginning. The algorithm
maintains two subarrays in a given array.
1. The subarray which is already sorted.
2. Remaining subarray which is unsorted.
In every iteration of selection sort, the minimum element (considering ascending order) from
the unsorted subarray is picked and moved to the sorted subarray.
Time Complexity: O(n2) as there are two nested loops.

Example:

ALGORITHM

1. Set MIN to location 0


2. Search the minimum element in the list
3. Swap with value at location MIN
4. Increment MIN to point to next element
5. Repeat until list is sorted

PSEUDO-CODE

procedure selection
sort list : array of
items
22
n : size of list

23
for i = 1 to n - 1
/* set current element as minimum*/
min = i

/* check the element to be minimum

*/ for j = i+1 to n
if list[j] < list[min] then
min = j;
end if
end for

/* swap the minimum element with the current


element*/ if indexMin != i then
swap list[min] and
list[i] end if
end for

end procedure

PROGRAM

#include <stdio.h>

void swap(int *xp, int *yp)


{
int temp = *xp;
*xp = *yp;
*yp = temp;
}

void selectionSort(int arr[], int n)


{
int i, j, min_idx;

// One by one move boundary of unsorted


subarray for (i = 0; i < n-1; i++)
{
// Find the minimum element in unsorted array
min_idx = i;
for (j = i+1; j < n; j++)
if (arr[j] < arr[min_idx])
24
min_idx = j;

// Swap the found minimum element with the first


element swap(&arr[min_idx], &arr[i]);
}
}

/* Function to print an array */


void printArray(int arr[], int
size)
{
int i;
for (i=0; i < size; i++)
printf("%d ",
arr[i]);
printf("\n");
}

// Driver program to test above


functions int main()
{
int arr[] = {64, 25, 12, 22, 11};
int n =
sizeof(arr)/sizeof(arr[0]);
selectionSort(arr, n);
printf("Sorted array: \n");
printArray(arr, n);
return 0;
}

25
5. INSERTION SORT

Insertion sort algorithm removes an element from the sorting list, and placing it into the
correct position in the already sorted part of the list, until no input elements left. The insertion
sort algorithm complexity depends on the input list. If the list is already sorted we have best
case,which has linear complexity O(n). If the list is reversed then we have worst case, quadratic
running time O(n^2). And the average case is also quadratic running time O(n^2), which make
the insertion sort not practical algorithm of choice for large n( where n is number of element in
the data structure), however insertion sort is one of the fastest algorithms for sorting very small
arrays.

Insertion Sorting Algorithm Complexity


1. Worst case performance O(n^2)
2. Best case performance O(n)
3. Average case performance O(n^2)

Example: Consider unsorted array

A[]=[7,4,5,2].

ALGORITHM

1. If it is the first element, it is already sorted. return 1;


26
2. Pick next element
3. Compare with all elements in the sorted sub-list

27
4. Shift all the elements in the sorted sub-list that is greater than the value to be sorted
5. Insert the value
6. Repeat until list is sorted

PSEUDO-CODE

for i ← 1 to length(A) -
1j←i
while j > 0 and A[j-1] > A[j]
swap A[j] and A[j-1]
j←j-
1 end
while
end for

PROGRAM:

#include <cstdlib>
#include <iostream>

using namespace std;

//member function
void insertion_sort(int arr[], int
length); void print_array(int array[],int
size);

int main()
{
int array[5]=
{5,4,3,2,1};
insertion_sort(array,5);
return 0;
}//end of main

void insertion_sort(int arr[], int length)


{
int i, j ,tmp;
for (i = 1; i < length; i++)

28
{
j = i;
while (j > 0 && arr[j - 1] > arr[j]) {

29
tmp = arr[j];
arr[j] = arr[j -
1]; arr[j - 1] =
tmp;
j--;
}//end of while loop
print_array(arr,5);
}//end of for loop
}//end of insertion_sort.

void print_array(int array[], int size)

{ cout<< "sorting: ";


int j;
for (j=0; j<size;j++)
for (j=0; j<size;j++)
cout <<" "<<
array[j]; cout <<
endl;
}//end of print_array

30
6. QUICK SORT
Quicksort is a divide and conquer algorithm. Quicksort first divides a large array into two
smaller sub-arrays: the low elements and the high elements. Quicksort can then recursively
sort the sub-arrays.
The steps are:

1. Pick an element, called a pivot, from the array.


2. Partitioning: reorder the array so that all elements with values less than the pivot come
before the pivot, while all elements with values 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.
3. Recursively apply the above steps to the sub-array of elements with smaller values
and separately to the sub-array of elements with greater values.

Example:

31
The shaded element is the pivot. It is always chosen as the last element of the partition. However,
always choosing the last element in the partition as the pivot in this way results in
poorperformance (O(n²)) on already sorted arrays, or arrays of identical elements. Since sub-
arrays ofsorted / identical elements crop up a lot towards the end of a sorting procedure on a
large set, versions of the quicksort algorithm which choose the pivot as the middle element run
much morequickly than the algorithm described in this diagram on large sets of numbers.

ALGORITHM

a) Quick Sort Pivot Algorithm


1. Choose the highest index value has pivot
2. Take two variables to point left and right of the list excluding pivot
3. left points to the low index
4. right points to the high
5. while value at left is less than pivot move right
6. while value at right is greater than pivot move left
7. if both step 5 and step 6 does not match swap left and right
8. if left ≥ right, the point where they met is new pivot

b) Quick Sort Algorithm


1. Make the right-most index value pivot
2. partition the array using pivot value
3. quicksort left partition recursively
4. quicksort right partition recursively

PSEUDO-CODE

a) Quick Sort Pivot Pseudo-code

function partitionFunc(left, right,


pivot) leftPointer = left
rightPointer = right - 1

while True do
while A[++leftPointer] < pivot do
//do-nothing
end while

while rightPointer > 0 && A[--rightPointer] > pivot do


//do-nothing
end while

32
if leftPointer >=
rightPointer break
else
swap leftPointer,rightPointer
end if

end while

swap leftPointer,right
return leftPointer

end function

b) Quick Sort Pseudo-code

procedure quickSort(left, right)

if right-left <= 0
return
else
pivot = A[right]
partition = partitionFunc(left, right,
pivot) quickSort(left,partition-1)
quickSort(partition+1,right)
end if

end procedure

PROGRAM

#include <iostream>
#include <vector>
using namespace
std;

/**
* Partition the elements of A, such that you first have elements smaller than
* "who", followed by eleemnts larger than "who". Return the last poistion of an
* element smaller or equal to "who".
*/
int partition(vector<int>& A, int left, int right, int who) {

33
for (int i=left; i<right; ++i) {

34
if (A[i] <= who) {
swap(A[i], A[left]);
left ++;
}
}
return left - 1;
}

/**
* Quick sort vector A, between index "left" and index "right".
*/
void qsort(vector<int>& A, int left, int right)
{ if (left >= right) return;

int middle = left + (right - left) / 2;


swap(A[middle], A[left]);
int midpoint = partition(A, left + 1, right, A[left]);
swap(A[left], A[midpoint]);
qsort(A, left, midpoint);
qsort(A, midpoint + 1,
right);
}

void printVector(vector<int>& A)
{ for (int i=0; i<A.size(); ++i) {
cout << A[i] << " ";
}
cout << endl;
}

void testPartition() {
int elements[] = {1, 3, 1, 1, 3};
vector<int> A(elements, elements +
5); int n = partition(A, 0, 5, 1);
cout << n <<
endl;
printVector(A);
}

35
void testSort() {
int elements[] = {1, 12, 2, 2, 2, 6, 20, 22};

36
vector<int> A(elements, elements +
8); qsort(A, 0, A.size());
printVector(A);
}

int main ()
{
testPartition();
cout << "--------------" << endl;
testSort();
return 0;
}

37
7. KNAPSACK PROBLEM USING GREEDY SOLUTION
Given a set of items, each with a weight and a value, determine a subset of items 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.

The knapsack problem is in combinatorial optimization problem. It appears as a sub-problem in


many, more complex mathematical models of real-world problems. One general approach to
difficult problems is to identify the most restrictive constraint, ignore the others, solve a
knapsack problem, and somehow adjust the solution to satisfy the ignored constraints.

Applications: In many cases of resource allocation along with some constraint, the problem can
be derived in a similar way of Knapsack problem. Following is a set of example.

 Finding the least wasteful way to cut raw materials


 Portfolio optimization
 Cutting stock problems

Problem Scenario

A thief is robbing a store and can carry a maximal weight of W into his knapsack. There are n
items available in the store and weight of ith item is w i and its profit is pi. What items should the
thief take?

In this context, the items should be selected in such a way that the thief will carry those items for
which he will gain maximum profit. Hence, the objective of the thief is to maximize the profit.

In the case of fractional knapsack, items can be broken into smaller pieces, hence the thief can
select fractions of items. According to the problem statement,

There are n items in the store

 Weight of ith item wi>0


 Profit for ith item pi>0 and
 Capacity of the Knapsack is W

In this fractional Knapsack problem, items can be broken into smaller pieces. So, the thief may
take only a fraction xi of ith item.

0⩽xi⩽1

38
The ith item contributes the weight xi.wi to the total weight in the knapsack and profit xi.pi to
the total profit.

Hence, the objective of this algorithm is to

subject to constraint,

It is clear that an optimal solution must fill the knapsack exactly, otherwise we could add a
fraction of one of the remaining items and increase the overall profit. Thus, an optimal solution
can be obtained by

In this context, first we need to sort those items according to the value of pi/wi, so that
(pi+1)/(wi+1)
≤ pi/wi . Here, x is an array to store the fraction of items.

ALGORITHM

 Assume knapsack holds weight W and items have value pi and weight wi
 Rank items by value/weight ratio: pi / wi
 Thus: pi / wi ≥ pj / wj, for all i ≤ j
 Consider items in order of decreasing ratio
 Take as much of each item as possible

PSEUDO-CODE

Greedy-Fractional-Knapsack (w[1..n], p[1..n], W)


for i = 1 to n
do x[i] = 0
weight = 0
39
for i = 1 to n
if weight + w[i] ≤ W then
x[i] = 1
weight = weight +
w[i] else
x[i] = (W - weight) /
w[i] weight = W
break
return x

PROGRAM

# include<stdio.h>

void knapsack(int n, float weight[], float profit[], float capacity)


{ float x[20], tp = 0;
int i, j, u;
u = capacity;

for (i = 0; i < n; i+
+) x[i] = 0.0;

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


if (weight[i] > u)
break;
else {
x[i] = 1.0;
tp = tp + profit[i];
u = u - weight[i];
}
}

if (i < n)
x[i] = u / weight[i];

tp = tp + (x[i] * profit[i]);

printf("\nThe result vector is:-


"); for (i = 0; i < n; i++)
printf("%f\t", x[i]);

printf("\nMaximum profit is:- %f", tp);


40
}

int main() {
float weight[20], profit[20], capacity;
int num, i, j;
float ratio[20], temp;

printf("\nEnter the no. of objects:-


"); scanf("%d", &num);

printf("\nEnter the wts and profits of each object:-


"); for (i = 0; i < num; i++) {
scanf("%f %f", &weight[i], &profit[i]);
}

printf("\nEnter the capacityacity of knapsack:- ");


scanf("%f", &capacity);

for (i = 0; i < num; i++) {


ratio[i] = profit[i] /
weight[i];
}

for (i = 0; i < num; i++) {


for (j = i + 1; j < num; j++)
{ if (ratio[i] < ratio[j]) {
temp = ratio[j];
ratio[j] = ratio[i];
ratio[i] = temp;

temp = weight[j];
weight[j] = weight[i];
weight[i] = temp;

temp = profit[j];
profit[j] = profit[i];
profit[i] = temp;
}
}
}

knapsack(num, weight, profit,


capacity); return(0);
}
41
8. TRAVELLING SALESMAN PROBLEM
A traveler needs to visit all the cities from a list, where distances between all the cities are known
and each city should be visited just once. The traveler seeks for the shortest possible route such
that he visits each city exactly once and returns to the origin city.

Travelling salesman problem is the most notorious computational problem. We can use brute-
force approach to evaluate every possible tour and select the best one. For n number of vertices
in a graph, there are (n - 1)! number of possibilities. Instead of brute-force using dynamic
programming approach, the solution can be obtained in lesser time, though there is no
polynomial time algorithm.

Let us consider a graph G = (V, E), where V is a set of cities and E is a set of weighted edges. An
edge e(u, v) represents that vertices u and v are connected. Distance between vertex u and v is
d(u, v), which should be non-negative.

Suppose we have started at city 1 and after visiting some cities now we are in city j. Hence, this
is a partial tour. We certainly need to know j, since this will determine which cities are most
convenient to visit next. We also need to know all the cities visited so far, so that we don't repeat
any of them. Hence, this is an appropriate sub-problem.

For a subset of cities S Є {1, 2, 3, ... , n} that includes 1, and j Є S, let C(S, j) be the length of the
shortest path visiting each node in S exactly once, starting at 1 and ending at j.

When |S| > 1, we define C(S, 1) = 𝖺 since the path cannot start and end at 1.

Now, let express C(S, j) in terms of smaller sub-problems. We need to start at 1 and end at j. We
should select the next city in such a way that

C(S,j) = min C(S−{j},i) + d(i,j) where i∈S and i≠jc(S,j)

= min C(s−{j},i) + d(i,j) where i∈S and i≠j

There are at the most 2n.n sub-problems and each one takes linear time to solve. Therefore, the
total running time is O(2 n.n2).

ALGORITHM

1. Consider city 1 as the starting and ending point. Since route is cyclic, we can
consider any point as starting point.
2. Generate all (n-1)! permutations of cities.
3. Calculate cost of every permutation and keep track of minimum cost permutation.
4. Return the permutation with minimum cost.

42
PSEUDO-CODE

C ({1}, 1) = 0
for s = 2 to n do
for all subsets S Є {1, 2, 3, … , n} of size s and containing 1
C (S, 1) = ∞
for all j Є S and j ≠ 1
C (S, j) = min {C (S – {j}, i) + d(i, j) for i Є S and i ≠ j}
Return minj C ({1, 2, 3, …, n}, j) + d(j, i)

PROGRAM

#include<stdio.h>

int ary[10][10],completed[10],n,cost=0;

void takeInput()
{
int i,j;

printf("Enter the number of villages:


"); scanf("%d",&n);

printf("\nEnter the Cost Matrix\

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


{
printf("\nEnter Elements of Row: %d\n",i+1);

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


scanf("%d",&ary[i][j]);

completed[i]=0;
}

printf("\n\nThe cost list is:");

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


{
printf("\n");

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


printf("\t%d",ary[i][j]);
}
43
}

void mincost(int city)


{
int i,ncity;

completed[city]=1;

printf("%d--->",city+1);
ncity=least(city);

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;

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


{
if((ary[c][i]!=0)&&(completed[i]==0))
if(ary[c][i]+ary[i][c] < min)
{
min=ary[i][0]+ary[c][i]; kmin=ary[c]
[i];
nc=i;
}
}

if(min!=999)
cost+=kmin;

return nc;
}

44
int main()
{
takeInput();

printf("\n\nThe Path is:\n");


mincost(0); //passing 0 because starting

vertex printf("\n\nMinimum cost is %d\n

",cost);

return 0;
}

45
9. MINIMUM SPANNING TREE (KRUSKAL’S ALGORITHM)
Prim's algorithm is a greedy algorithm that finds a minimum spanning tree for a weighted
undirected 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 operates by
building this tree one vertex at a time, from an arbitrary starting vertex, at each step adding the
cheapest possible connection from the tree to another vertex.

The algorithm may informally be described as performing the following steps:

1. Initialize a tree with a single vertex, chosen arbitrarily from the graph.
2. Grow the tree by one edge: of the edges that connect the tree to vertices not yet in
the tree, find the minimum-weight edge, and transfer it to the tree.
3. Repeat step 2 (until all vertices are in the tree).

ALGORITHM

1. Sort all the edges in non-decreasing order of their weight.


2. Pick the smallest edge. Check if it forms a cycle with the spanning tree formed so far.
If cycle is not formed, include this edge. Else, discard it.
3. Repeat step#2 until there are (V-1) edges in the spanning tree.

PSEUDO-CODE

A=∅
foreach v ∈ G.V
MAKE-SET(v)
foreach (u, v) in G.E ordered by weight(u, v),
increasing if FIND-SET(u) ≠ FIND-SET(v)
A = A 𝖴 {(u, v)}
UNION(FIND-SET(u), FIND-SET(v))
return A

PROGRAM

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// a structure to represent a weighted edge in graph

46
struct Edge
{
int src, dest, weight;
};

// a structure to represent a connected, undirected


// and weighted
graph struct Graph
{
// V-> Number of vertices, E-> Number of edges
int V, E;

// graph is represented as an array of edges.


// Since the graph is undirected, the edge
// from src to dest is also edge from dest
// to src. Both are counted as 1 edge
here. struct Edge* edge;
};

// Creates a graph with V vertices and E


edges struct Graph* createGraph(int V, int E)
{
struct Graph* graph = new
Graph; graph->V = V;
graph->E = E;

graph->edge = new Edge[E];

return graph;
}

// A structure to represent a subset for union-


find struct subset
{
int parent;
int rank;
};

// A utility function to find set of an element i


// (uses path compression
technique) int find(struct subset
subsets[], int i)
{
// find root and make root as parent of i
// (path compression)
47
if (subsets[i].parent != i)

48
subsets[i].parent = find(subsets, subsets[i].parent);

return subsets[i].parent;
}

// A function that does union of two sets of x and y


// (uses union by rank)
void Union(struct subset subsets[], int x, int y)
{
int xroot = find(subsets, x);
int yroot = find(subsets, y);

// Attach smaller rank tree under root of high


// rank tree (Union by Rank)
if (subsets[xroot].rank <
subsets[yroot].rank) subsets[xroot].parent
= yroot;
else if (subsets[xroot].rank >
subsets[yroot].rank) subsets[yroot].parent =
xroot;

// If ranks are same, then make one as root and


// increment its rank by one
else
{
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

// Compare two edges according to their weights.


// Used in qsort() for sorting an array of
edges int myComp(const void* a, const
void* b)
{
struct Edge* a1 = (struct Edge*)a;
struct Edge* b1 = (struct Edge*)b;
return a1->weight > b1->weight;
}

// The main function to construct MST using Kruskal's


algorithm void KruskalMST(struct Graph* graph)
{
int V = graph->V;
struct Edge result[V]; // Tnis will store the resultant MST
49
int e = 0; // An index variable, used for result[]
int i = 0; // An index variable, used for sorted edges

50
// Step 1: Sort all the edges in non-decreasing
// order of their weight. If we are not allowed to
// change the given graph, we can create a copy of
// array of edges
qsort(graph->edge, graph->E, sizeof(graph->edge[0]), myComp);

// Allocate memory for creating V


ssubsets struct subset *subsets =
(struct subset*) malloc( V * sizeof(struct subset) );

// Create V subsets with single


elements for (int v = 0; v < V; ++v)
{
subsets[v].parent = v;
subsets[v].rank = 0;
}

// Number of edges to be taken is equal to V-


1 while (e < V - 1 && i < graph->E)
{
// Step 2: Pick the smallest edge. And increment
// the index for next iteration
struct Edge next_edge = graph->edge[i++];

int x = find(subsets, next_edge.src);


int y = find(subsets,
next_edge.dest);

// If including this edge does't cause cycle,


// include it in result and increment the index
// of result for next edge
if (x != y)
{
result[e++] =
next_edge;
Union(subsets, x, y);
}
// Else discard the next_edge
}

// print the contents of result[] to display the


// built MST
printf("Following are the edges in the constructed MST\n");
for (i = 0; i < e; ++i)
printf("%d -- %d == %d\n", result[i].src, result[i].dest,
51
result[i].weight); return;
}

52
10. N QUEEN PROBLEM USING BACK TRACKING

If we imagine the squares of the chessboard being numbered as the indices of the two
dimensional array A(l:n, l:n) then we observe that for every element on the same diagonal which
runs from the upper left to the lower right, each element has the same "row - column" value.
Also, every element on the same diagonal which goes from the upper right to the lower left has
the same "row + column" value. Suppose two queens are placed at positions (i,j) and (k, /).Then
by the above they are on the same diagonal only if
i - j = k - I or i + j = k + I.
The first equation implies
j-l=i-k
while the second implies
j-l=k-i
Therefore two queens lie on the same diagonal if and only if lj - /I = Ii - kl.

ALGORITHM

Procedure PLACE(k) returns a boolean value which is true if the kth queen can be placed at
the current value of x(k). It tests both if X(k) is distinct from all previous values X(l), ... , X(k -
1) and also if there is no other queen on the same diagonal. Its computing time is O(k - 1).

PLACE(k)
I /returns true if a queen can be placed in kth row and/ I I IX(k)th column. Otherwise it returns
false.I I /IX is a global array whose first k values have been set.I I I I ABS(r) returns the
absolute value of rl I global X(l: k ); integer i, k

for i - 1 to k do
if X(i) = X(k) I !two in the same column//
or ABS(X(i) - X(k)) = ABS(i - k) //in the same diagonal//
then retum(false)
endif
repeat
return( true)
end PLACE

NQUEENS(n)
I /using backtracking this procedure prints all possible placements of / I I In queens on an n x n
chessboard so that they are nonattacking/ I

integer k, n, X(l:n)
X(l) - 0; k - 1 Ilk is the current row; X(k) the current column/ I
53
while k > 0 do //for aU rows do//
X(k) - X(k) + 1 I /move to the next column/ I
While X(k)<=n and not PLACE(k) do //can this queen be placed?//
X(k) - X(k) + 1
repeat
if X(k) ~ n ! la position is found//
then if k = n I !is a solution complete? I I
then print(X) //yes, print the array/ I
else k - k + 1; X(k) - 0 I Igo to the next row//
endif
else k - k - 1 I /backtrack/ I
endif
repeat

endNQUEENS

PROGRAM

/*This program is to implement n-queen's problem using


backtracking*/ #include<stdio.h>
#include<conio.h>
#include<math.h>
#include<process.h>

int board[20];
int count;
void main()
{
int n,i,j;
void queen(int row, int
n); clrscr();
printf("\n\t Program for queen's using
backtracking"); printf("Enter number of queen's ");
scanf("%d",&n);
queen(1,n); //trace using
backtrack getch();
}

54
/*This function is for printing the solution to n-queen's
problem*/ void print_board(int n)
{
int i,j;
printf("\n\n solution %d:\n\n",++count);
//number of solution
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++) //for n*n board
{
if(board[i]==j)
printf("\tQ"); //Queen at i,j position
else
printf("\t-"); //empty slot
}
}

printf("\n Press any key to continue....");


getch();
}

/*This function is for checking for the conflicts.If there is no conflict for the desired position
it returns 1 otherwise it returns 0*/
int place(int row ,int column)
{
int i;
for(i=1;i<=row-1;i++)
{
//checking for column and diagonal
conflicts if(board[i]==column)
return 0;
else
55
if(abs(board[i]-column)==abs(i-row))

56
return 0;
}
//no conflicts hence Queen can be
placedreturn 1;
}

/*By this function we try the next free slot and check for proper positioning
of queen */void queen(int row, int n)
{
int column;
for(column=1;column<=n;column
++)
{
if(place(row,column))
{
board[row]=column; //no conflicts so place
queenif(row==n)//dead end
print_board(n); //printing the board configuration
}
else //try queen with next
positionqueen(row+1,n);
}
}

44
11. Sort a given set of n integer elements using Quick Sort method and compute its time
complexity. Run the program for varied values of n> 5000 and record the time taken to sort.
Plot a graph of the time taken versus non graph sheet. The elements can be read from a file or
can be generated using the random number generator. Demonstrate using Java how the
divide and- conquer method works along with its time complexity analysis: worst case,
average case and best case.

import java.util.Random;
import java.util.Scanner;
class QuickSort {
static int comparisons = 0;
static int[] arr;
static void quickSort(int low, int high) {
if (low < high) {
comparisons += 1;
int j = partition(low, high);
quickSort(low, j - 1);
quickSort(j + 1, high);
}
}
static int partition(int low, int high) {
int pivot = arr[low];
int i = low, j = high;
while (i < j) {
comparisons += 1;
while (i < high && arr[i] <= pivot) {
comparisons += 2;
i = i + 1;
}
while (j > low && arr[j] >= pivot) {
comparisons += 2;
j = j - 1;
}
if (i < j) {
comparisons += 1;
interchange(i, j);
}
}
arr[low] = arr[j];
arr[j] = pivot;
return j;
}
static void interchange(int i, int j) {
int temp = arr[i];
arr[i] = arr[j]; 45
arr[j] = temp;
}
public static void main(String[] args) {
int n;
Scanner scanner = new Scanner(System.in);
System.out.print("Enter value of n: ");
n = scanner.nextInt();
arr = new int[n];
System.out.println("Quick Sort");
System.out.println("1. Best/Average Case");
System.out.println("2. Worst Case");
int ch = scanner.nextInt();
switch (ch) {
case 1:
Random random = new Random(3000);
for (int i = 0; i < n; i++) {
arr[i] = random.nextInt();
}
break;
case 2:
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
break;
}
long start = System.nanoTime();
quickSort(0, n - 1);
long end = System.nanoTime();
System.out.println("Sorted Array");
for (int i = 0; i < n; i++) {
System.out.println(arr[i]);
}
System.out.println("Time taken: " + (end - start));
System.out.println("Comparisons: " + comparisons);
}
}

Output:
N=5001
Average and Best Case:

46
Time taken: 3128299
Comparisons: 170690
Worst Case
N=5001

12. Sort a given set of n integer elements using Merge Sort method and compute its time complexity.
Run the program for varied values of n> 5000, and record the time taken to sort. Plot a graph of the
time taken versus non graph sheet. The elements can be read from a file or can be generated using the
random number generator. Demonstrate how the divide and- conquer method works along with its
time complexity analysis: worst case, average case and best case.
import java.util.Random;
import java.util.Scanner;
public class MergeSort
{
public static void main(String[] args)
{
int a[]= new int[100000];
Scanner in = new Scanner(System.in);
long start, end;
System.out.print("Enter the number of elements to be sorted: ");
int n = in.nextInt();
Random rand= new Random();
for(int i=0;i<n;i++)
a[i]=rand.nextInt(2000);
System.out.println("Array elements to be sorted
are:"); for(int i=0; i<n; i++)
System.out.println(a[i]);
start=System.nanoTime();
mergesort(a,0,n-1);
end=System.nanoTime();
47
System.out.println("\nThe sorted elements are: ");
for(int i=0; i<n; i++)
System.out.println(a[i]);
System.out.println("\nThe time taken to sort is "+(end-start)+"ns");
}
static void mergesort(int a[], int low, int high)
{
int mid;
if(low < high)
{
mid = (low+high)/2;
mergesort(a, low, mid);
mergesort(a, mid+1, high);
merge(a, low, mid, high);
}
}
static void merge(int a[], int low, int mid, int high)
{
int i, j, h, k, b[]= new int[100000];
h=low; i=low; j=mid+1;
while((h<=mid) && (j<=high))
{
if(a[h] < a[j])
{
b[i]=a[h];
h=h+1;
}
else
{
b[i] = a[j];
j=j+1;
}
i = i+1;
}
if(h > mid)
{
for(k=j; k<=high; k++)
{
b[i]=a[k];
i= i+1;
}
}
else
{
for(k=h;k<=mid;k++)
48
{
b[i]=a[k];
i= i+1;
}
}
for(k=low; k<= high; k++)
a[k] = b[k];
}
}
Output
Value of n = 5100
Random 5100 numbers will be generated

49
50
13.a) 0/1 Knapsack problem using Greedy Method
import java.util.Scanner;
public class Knap2
{
public static void main(String[] args)
{
int i,j=0,max_qty,m,n;
51
float sum=0,max;
Scanner sc = new Scanner(System.in);
int array[][]=new int[2][20];
System.out.print("Enter no of items: ");
n=sc.nextInt();
System.out.println("Enter the weights of each items:");
for(i=0;i<n;i++)
array[0][i]=sc.nextInt();
System.out.println("Enter the values of each items:");
for(i=0;i<n;i++)
array[1][i]=sc.nextInt();
System.out.println("Enter maximum volume of knapsack :");
max_qty=sc.nextInt();
m=max_qty;
while(m>=0)
{
max=0;
for(i=0;i<n;i++)
{
if(((float)array[1][i])/((float)array[0][i])>max)
{
max=((float)array[1][i])/((float)array[0][i]);
j=i;
}
}
if(array[0][j]>m)
{
System.out.println("Quantity of item number: "+ (j+1) + " added is " +m);
sum+=m*max;
m=-1;
}
else
{
System.out.println("Quantity of item number: " + (j+1) + " added is " + array[0][j]);
m-=array[0][j];
sum+=(float)array[1][j];
array[1][j]=0;
}
}
System.out.println("The total profit is " + sum);
sc.close();
}
}
Output

52
13. b) 0/1 Knapsack problem using Dynamic Programming Method
import java.util.Scanner;
public class Knap1
{
static int max(int a, int b)
{
return (a > b)? a : b;
}
static int knapSack(int W, int wt[], int val[], int n)
{
int i, w;
int [][]K = new int[n+1][W+1];
for (i = 0; i <= n; i++)
{
for (w = 0; w <= W; w++)
{
if (i==0 || w==0)
K[i][w] = 0;
else if (wt[i-1] <= w)
K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]], K[i-1][w]);
else
K[i][w] = K[i-1][w];
}
}
return K[n][W];
}
public static void main(String args[])
{
53
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number of items: ");
int n = sc.nextInt();
System.out.println("Enter the items weights: ");
int []wt = new int[n];
for(int i=0; i<n; i++)
wt[i] = sc.nextInt();
System.out.println("Enter the items values: ");
int []val = new int[n];
for(int i=0; i<n; i++)
val[i] = sc.nextInt();
System.out.println("Enter the maximum capacity: ");
int W = sc.nextInt();
System.out.println("The maximum value that can be put in a knapsack of capacity W is: " +
knapSack(W, wt, val, n));
sc.close();
}
}

14
From a given vertex in a weighted connected graph, find shortest paths to other vertices
using Dijkstra’s algorithm.

ALGO- Let the node at which we are starting at be called the initial node. Let the distance of
node Y be the distance from the initial node to Y. Dijkstra's algorithm will initially start with infinite
distances and will try to improve them step by step.

54
1. Mark all nodes unvisited. Create a set of all the unvisited nodes called the unvisited set.
2. Assign to every node a tentative distance value: set it to zero for our initial node and
to infinity for all other nodes. Set the initial node as current.[15]
3. For the current node, consider all of its unvisited neighbours and calculate
their tentative distances[Note 1] through the current node. Compare the newly
calculated tentative distance to the current assigned value and assign the smaller one. For
example, if the current node A is marked with a distance of 6, and the edge connecting it
with a neighbour B has length 2, then the distance to B through A will be 6 + 2 = 8. If B
was previously marked with a distance greater than 8 then change it to 8. Otherwise, the
current value will be kept.
4. When we are done considering all of the unvisited neighbours of the current node, mark
the current node as visited and remove it from the unvisited set. A visited node will never
be checked again.
5. If the destination node has been marked visited (when planning a route between two
specific nodes) or if the smallest tentative distance among the nodes in the unvisited set is
infinity (when planning a complete traversal; occurs when there is no connection
between the initial node and remaining unvisited nodes), then stop. The algorithm has
finished.
6. Otherwise, select the unvisited node that is marked with the smallest tentative distance,
set it as the new "current node", and go back to step 3.
When planning a route, it is actually not necessary to wait until the destination node is "visited" as
above: the algorithm can stop once the destination node has the smallest tentative distance among
all "unvisited" nodes (and thus could be selected as the next "current").

#include<stdio.h>

#include<conio.h>

#define infinity

999

void dij(int n,int v,int cost[10][10],int dist[100])

int i,u,count,w,flag[10],min;

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

flag[i]=0,dist[i]=cost[v][i];

count=2;

55
while(count<=n)

56
min=99;

for(w=1;w<=n;w++)

if(dist[w]<min && !

flag[w])

min=dist[w],u=w;

flag[u]=1;

count++;

for(w=1;w<=n;w++)

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

flag[w]) dist[w]=dist[u]+cost[u][w];

void main()

int n,v,i,j,cost[10][10],dist[10];

clrscr();

printf("\n Enter the number of nodes:");

scanf("%d",&n);

printf("\n Enter the cost matrix:\

n"); for(i=1;i<=n;i++)

for(j=1;j<=n;j++)

scanf("%d",&cost[i][j]);

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

57
cost[i][j]=infinity;

58
}

printf("\n Enter the source

matrix:"); scanf("%d",&v);

dij(n,v,cost,dist);

printf("\n Shortest path:\

n"); for(i=1;i<=n;i++)

if(i!=v)

printf("%d->%d,cost=%d\n",v,i,dist[i]);

getch();

Sample Output:

59
15
Aim- Find Minimum Cost Spanning Tree of a given connected undirected graph using Kruskal's
algorithm. Use Union-Find algorithms in your program
1. Begin
2. Create the edge list of given graph, with their weights.
3. Sort the edge list according to their weights in ascending order.
4. Draw all the nodes to create skeleton for spanning tree.
5. Pick up the edge at the top of the edge list (i.e. edge with minimum weight).
6. Remove this edge from the edge list.
7. Connect the vertices in the skeleton with given edge. If by connecting the vertices, a cycle
is created in the skeleton, then discard this edge.
8. Repeat steps 5 to 7, until n-1 edges are added or list of edges is over.
9. Return

Pseudocode- #include<stdio.h>

#define MAX 30

typedef struct edge


{
int u,v,w;
}edge;

typedef struct edgelist


{
edge data[MAX];
int n;
}edgelist;

edgelist elist;

int G[MAX][MAX],n;
edgelist spanlist;

void kruskal();
int find(int belongs[],int vertexno);
void union1(int belongs[],int c1,int c2);
void sort();
void print();

void main()
{
int i,j,total_cost;
printf("\nEnter number of vertices:");
scanf("%d",&n);
60
printf("\nEnter the adjacency matrix:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&G[i][j]);
kruskal();
print();
}

void kruskal()
{
int belongs[MAX],i,j,cno1,cno2;
elist.n=0;

for(i=1;i<n;i++)
for(j=0;j<i;j++)
{ if(G[i][j]!
=0)
{
elist.data[elist.n].u=i;
elist.data[elist.n].v=j;
elist.data[elist.n].w=G[i][j];
elist.n++;
}
}

sort(); for(i=0;i<n;i+
+) belongs[i]=i;
spanlist.n=0;
for(i=0;i<elist.n;i++)
{
cno1=find(belongs,elist.data[i].u);
cno2=find(belongs,elist.data[i].v);
if(cno1!=cno2)
{
spanlist.data[spanlist.n]=elist.data[i];
spanlist.n=spanlist.n+1;
union1(belongs,cno1,cno2);
}
}
}

int find(int belongs[],int vertexno)


{
return(belongs[vertexno]);

61
}

void union1(int belongs[],int c1,int c2)


{
int i;
for(i=0;i<n;i++)
if(belongs[i]==c2)
belongs[i]=c1;
}

void sort()
{
int i,j;
edge temp;
for(i=1;i<elist.n;i++)
for(j=0;j<elist.n-1;j++)
if(elist.data[j].w>elist.data[j+1].w)
{
temp=elist.data[j];
elist.data[j]=elist.data[j+1];
elist.data[j+1]=temp;
}
}

void print()
{
int i,cost=0;
for(i=0;i<spanlist.n;i++)
{
printf("\n%d\t%d\t%d",spanlist.data[i].u,spanlist.data[i].v,spanlist.data[i].w);
cost=cost+spanlist.data[i].w;
}

printf("\n\nCost of the spanning tree=%d",cost);


}

62
16
Aim- . Find Minimum Cost Spanning Tree of a given undirected graph using Prim’s algorithm.

Algo- Step 1: Select a starting vertex.


1. Step 2: Repeat Steps 3 and 4 until there are fringe vertices.
2. Step 3: Select an edge e connecting the tree vertex and fringe vertex that has minimum weight.
3. Step 4: Add the selected edge and the vertex to the minimum spanning tree T. [END OF LOOP]
4. Step 5: EXIT.

Pseudocode- #include<stdio.h>
#include<conio.h>
int a,b,u,v,n,i,j,ne=1;
int visited[10]= { 0},min,mincost=0,cost[10][10];
void main() {
clrscr();
printf("\n Enter the number of nodes:");
scanf("%d",&n);
printf("\n Enter the adjacency matrix:\n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++) {
scanf("%d",&cost[i][j]); if(cost[i]
[j]==0)
cost[i][j]=999;
}
visited[1]=1;
printf("\n");
63
while(ne<n) {
for (i=1,min=999;i<=n;i++)
for (j=1;j<=n;j++)
if(cost[i][j]<min)
if(visited[i]!=0) {
min=cost[i][j];
a=u=i;
b=v=j;
}
if(visited[u]==0 || visited[v]==0)
{
printf("\n Edge %d:(%d %d) cost:%d",ne++,a,b,min);
mincost+=min;
visited[b]=1;
}
cost[a][b]=cost[b][a]=999;
}
printf("\n Minimun cost=%d",mincost);
getch();
}

Output

17 a. All-Pairs Shortest Paths Problem using Floyd’s algorithm


64
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.

Example:
Input:
graph[][] = { {0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0} }
which represents the following graph
10
(0)------->(3)
| /|\
5| |
| |1
\|/ |
(1)------->(2)
3
Note that the value of graph[i][j] is 0 if i is equal to j
And graph[i][j] is INF (infinite) if there is no edge from vertex i to j.

Output:
Shortest distance matrix
0 5 8 9
INF 0 3 4
INF INF 0 1
INF INF INF 0
Floyd Warshall Algorithm
We initialize the solution matrix same as the input graph matrix as a first step. Then we update
the solution matrix by considering all vertices as an intermediate vertex. The idea is to one by
one pick all vertices and updates all shortest paths which include the picked vertex as an
intermediate vertex in the shortest path. When we pick vertex number k as an intermediate
vertex, we already have considered vertices {0, 1, 2, .. k-1} as intermediate vertices. For every
pair (i, j) of the source and destination vertices respectively, there are two possible cases.
1) k is not an intermediate vertex in shortest path from i to j. We keep the value of dist[i][j] as it
is.
2) k is an intermediate vertex in shortest path from i to j. We update the value of dist[i][j] as
dist[i][k] + dist[k][j] if dist[i][j] > dist[i][k] + dist[k][j]
The following figure shows the above optimal substructure property in the all-pairs shortest path
problem.

// C Program for Floyd Warshall Algorithm


65
#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 an 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.
----> After the end of an 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++)
66
{
// 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);
}

/* A utility function to print solution */


void printSolution(int dist[][V])
{
printf ("The 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++)
{
if (dist[i][j] == INF)
printf("%7s", "INF");
else
printf ("%7d", dist[i][j]);
}
printf("\n");
}
}

// driver program to test above function


int main()
{
/* Let us create the following weighted graph
10
(0)------->(3)
| /|\
67
5| |
| |1
\|/ |
(1)------->(2)
3 */
int graph[V][V] = { {0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0}
};

// Print the solution


floydWarshall(graph);
return 0;
}

17 b. Travelling Sales Person problem using Dynamic programming


Travelling Salesman Problem (TSP): Given a set of cities and distance between every pair of
cities, the problem is to find the shortest possible route that visits every city exactly once and
returns to the starting point.
Note the difference between Hamiltonian Cycle and TSP. The Hamiltoninan cycle problem is to
find if there exist a tour that visits every city exactly once. Here we know that Hamiltonian Tour
exists (because the graph is complete) and in fact many such tours exist, the problem is to find a
minimum weight Hamiltonian Cycle.

For example, consider the graph shown in figure on right side. A TSP tour in the graph is 1 -2-4-
3-1. The cost of the tour is 10+25+30+15 which is 80.
The problem is a famous NP hard problem. There is no polynomial time know solution for this
problem.
Dynamic Programming:
Let the given set of vertices be {1, 2, 3, 4,….n}. Let us consider 1 as starting and ending point
of output. For every other vertex i (other than 1), we find the minimum cost path with 1 as the
starting point, i as the ending point and all vertices appearing exactly once. Let the cost of this
68
path be cost(i), the cost of corresponding Cycle would be cost(i) + dist(i, 1) where dist(i, 1) is
the distance from i to 1. Finally, we return the minimum of all [cost(i) + dist(i, 1)] values. This
looks simple so far. Now the question is how to get cost(i)?
To calculate cost(i) using Dynamic Programming, we need to have some recursive relation in
terms of sub-problems. Let us define a term C(S, i) be the cost of the minimum cost path visiting
each vertex in set S exactly once, starting at 1 and ending at i.
We start with all subsets of size 2 and calculate C(S, i) for all subsets where S is the subset, then
we calculate C(S, i) for all subsets S of size 3 and so on. Note that 1 must be present in every
subset.
If size of S is 2, then S must be {1, i},
C(S, i) = dist(1, i)
Else if size of S is greater than 2.
C(S, i) = min { C(S-{i}, j) + dis(j, i)} where j belongs to S, j != i and j != 1.
Output of Given Graph:
minimum weight Hamiltonian Cycle :
10 + 25 + 30 + 15 := 80
// CPP program to implement traveling salesman
// problem using naive approach.
#include <bits/stdc++.h>
using namespace std;
#define V 4

// implementation of traveling Salesman Problem


int travllingSalesmanProblem(int graph[][V], int s)
{
// store all vertex apart from source vertex
vector<int> vertex;
for (int i = 0; i < V; i++)
if (i != s)
vertex.push_back(i);

// store minimum weight Hamiltonian Cycle.


int min_path = INT_MAX;
do {

// store current Path weight(cost)


int current_pathweight = 0;

// compute current path weight


int k = s;
for (int i = 0; i < vertex.size(); i++) {
69
current_pathweight += graph[k][vertex[i]];
k = vertex[i];
}
current_pathweight += graph[k][s];

// update minimum
min_path = min(min_path, current_pathweight);

} while (
next_permutation(vertex.begin(), vertex.end()));

return min_path;
}

// Driver Code
int main()
{
// matrix representation of graph
int graph[][V] = { { 0, 10, 15, 20 },
{ 10, 0, 35, 25 },
{ 15, 35, 0, 30 },
{ 20, 25, 30, 0 } };
int s = 0;
cout << travllingSalesmanProblem(graph, s) << endl;
return 0;
}

18 Design and implement to 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}. Display a suitable message, if the
given problem instance doesn't have a solution.
Sum of Subsets
Subset-Sum Problem is to find a subset of a given set S= {s1, s2… sn} of n positive integers whose
sum is equal to a given positive integer d. It is assumed that the set‟s elements are sorted in
increasing order. The state-space tree can then be constructed as a binary tree and applying
backtracking algorithm, the solutions could be obtained. Some instances of the problem may have
no solutions
Complexity: Subset sum problem solved using backtracking generates at each step maximal two
new subtrees, and the running time of the bounding functions is linear, so the running time is
O(2n).

70
#include<stdio.h>
#include<conio.h>
int s[10],d,n,set[10],count=0;
void display(int);
int flag=0;
void main()
{
int subset(int,int);
int i;
clrscr();
printf("Enter the number of elements in set\n");
scanf("%d",&n);
printf("Enter the set values\n");
for(i=0;i<n;++i)
scanf("%d",&s[i]);
printf("Enter the sum\n");
scanf("%d",&d);
printf("The progrm output is\n");
subset(0,0);
if(flag==0)
printf("there is no solution");
getch();
}
int subset(int sum,int i)
{
if(sum==d)
{
flag=1;
display(count);
return;
}
if(sum>d||i>=n)
return;
else
{
set[count]=s[i];

71
count++;
subset(sum+s[i],i+1);
count--;
subset(sum,i+1);
}
}
void display(int count)
{
int i;
printf("{");
for(i=0;i<count;i++)
printf("%d",set[i]);
printf("}");
}

19. Design and implement to find all Hamiltonian Cycles in a connected undirected Graph G
of n vertices using backtracking principle.
Hamiltonian Path in an undirected graph is a path that visits each vertex exactly once. A
Hamiltonian cycle (or Hamiltonian circuit) is a Hamiltonian Path such that there is an edge (in
the graph) from the last vertex to the first vertex of the Hamiltonian Path. Determine whether a
given graph contains Hamiltonian Cycle or not. If it contains, then prints the path. Following are
the input and output of the required function.
Input:
A 2D array graph[V][V] where V is the number of vertices in graph and graph[V][V] is
adjacency matrix representation of the graph. A value graph[i][j] is 1 if there is a direct edge
from i to j, otherwise graph[i][j] is 0.
Output:
An array path[V] that should contain the Hamiltonian Path. path[i] should represent the ith
vertex in the Hamiltonian Path. The code should also return false if there is no Hamiltonian
Cycle in the graph.
For example, a Hamiltonian Cycle in the following graph is {0, 1, 2, 4, 3, 0}.
(0)--(1)--(2)
| /\ |
| / \ |
|/ \|
(3) (4)
And the following graph doesn’t contain any Hamiltonian Cycle.
(0)--(1)--(2)
72
| /\ |
| / \ |
|/ \|
(3) (4)
Backtracking Algorithm
Create an empty path array and add vertex 0 to it. Add other vertices, starting from the vertex 1.
Before adding a vertex, check for whether it is adjacent to the previously added vertex and not
already added. If we find such a vertex, we add the vertex as part of the solution. If we do not
find a vertex then we return false.
Implementation of Backtracking solution
Following are implementations of the Backtracking solution.
/* C program for solution of Hamiltonian Cycle problem
using backtracking */
#include<stdio.h>

// Number of vertices in the graph


#define V 5

void printSolution(int path[]);

/* A utility function to check if the vertex v can be added at


index 'pos' in the Hamiltonian Cycle constructed so far (stored
in 'path[]') */
bool isSafe(int v, bool graph[V][V], int path[], int pos)
{
/* Check if this vertex is an adjacent vertex of the previously
added vertex. */
if (graph [ path[pos-1] ][ v ] == 0)
return false;

/* Check if the vertex has already been included.


This step can be optimized by creating an array of size V */
for (int i = 0; i < pos; i++)
if (path[i] == v)
return false;

return true;
}

/* A recursive utility function to solve hamiltonian cycle problem */


bool hamCycleUtil(bool graph[V][V], int path[], int pos)
{
/* base case: If all vertices are included in Hamiltonian Cycle */
73
if (pos == V)
{
// And if there is an edge from the last included vertex to the
// first vertex
if ( graph[ path[pos-1] ][ path[0] ] == 1 )
return true;
else
return false;
}

// Try different vertices as a next candidate in Hamiltonian Cycle.


// We don't try for 0 as we included 0 as starting point in hamCycle()
for (int v = 1; v < V; v++)
{
/* Check if this vertex can be added to Hamiltonian Cycle */
if (isSafe(v, graph, path, pos))
{
path[pos] = v;

/* recur to construct rest of the path */


if (hamCycleUtil (graph, path, pos+1) == true)
return true;

/* If adding vertex v doesn't lead to a solution,


then remove it */
path[pos] = -1;
}
}

/* If no vertex can be added to Hamiltonian Cycle constructed so far,


then return false */
return false;
}

/* This function solves the Hamiltonian Cycle problem using Backtracking.


It mainly uses hamCycleUtil() to solve the problem. It returns false
if there is no Hamiltonian Cycle possible, otherwise return true and
prints the path. Please note that there may be more than one solutions,
this function prints one of the feasible solutions. */
bool hamCycle(bool graph[V][V])
{
int *path = new int[V];
for (int i = 0; i < V; i++)
path[i] = -1;

74
/* Let us put vertex 0 as the first vertex in the path. If there is
a Hamiltonian Cycle, then the path can be started from any point
of the cycle as the graph is undirected */
path[0] = 0;
if ( hamCycleUtil(graph, path, 1) == false )
{
printf("\nSolution does not exist");
return false;
}

printSolution(path);
return true;
}

/* A utility function to print solution */


void printSolution(int path[])
{
printf ("Solution Exists:"
" Following is one Hamiltonian Cycle \n");
for (int i = 0; i < V; i++)
printf(" %d ", path[i]);

// Let us print the first vertex again to show the complete cycle
printf(" %d ", path[0]);
printf("\n");
}

// driver program to test above function


int main()
{
/* Let us create the following graph
(0)--(1)--(2)
| /\ |
| / \ |
|/ \|
(3)-------(4) */
bool graph1[V][V] = {{0, 1, 0, 1, 0},
{1, 0, 1, 1, 1},
{0, 1, 0, 0, 1},
{1, 1, 0, 0, 1},
{0, 1, 1, 1, 0},
};

// Print the solution


hamCycle(graph1);
75
/* Let us create the following graph
(0)--(1)--(2)
| /\ |
| / \ |
|/ \|
(3) (4) */
bool graph2[V][V] = {{0, 1, 0, 1, 0},
{1, 0, 1, 1, 1},
{0, 1, 0, 0, 1},
{1, 1, 0, 0, 0},
{0, 1, 1, 0, 0},
};

// Print the solution


hamCycle(graph2);

return 0;
}

76

You might also like