0% found this document useful (0 votes)
30 views48 pages

Daa Lab Manual

AD3551-DAA lab manual

Uploaded by

Swathy Boopathy
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)
30 views48 pages

Daa Lab Manual

AD3551-DAA lab manual

Uploaded by

Swathy Boopathy
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/ 48

Exp.

No :
Date :
Recursive and Non-Recursive Algorithms - Binary Search
Aim:
To implement recursive and non-recursive algorithm for binary search
Algorithm for Binary Search
Let key be the element we are searching for, and the array be sorted in the ascending order.
1. Compare key with the middle element of the array.
2. If key matches with the middle element, we return the index of the middle element.
3. Else if key is greater than the middle element, it means that key can only lie in
the right half subarray after the middle element. So we repeat steps 1 to 4 for the
right half subarray and leave the left half subarray.
4. Else if key is smaller than the middle element, it means that target can only lie in
the left half subarray before the middle element. So, we repeat steps 1 to 4 for the
left half subarray.
5. We will keep doing that till we find key or there is no element left in the subarray
being considered.
Source code:
#include <stdio.h>
int binarySearch(int arr[], int left, int right, int key) {
if (right >= left) {
int mid = left + (right - left) / 2;
if (arr[mid] == key)
return mid;
if (arr[mid] > key) {
return binarySearch(arr, left, mid - 1, key);
}
return binarySearch(arr, mid + 1, right, key);
}
return -1;
}
int main(void) {
int arr[] = {2, 5, 8, 12, 16, 23, 38, 56, 72, 91};
int size = sizeof(arr) / sizeof(arr[0]);
int key = 23;
int index = binarySearch(arr, 0, size - 1, key);
if (index == -1) {
printf("Element is not present in array");
}
else {
printf("Element is present at index %d", index);
}
return 0;
}
Non-recursive
# include <stdio.h>
int binarysearch(int a[],int low,int high,int key)
{
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid]==key)
{
return mid;
}
else if(key>a[mid])
{
low=mid+1;
}
else if(key<a[mid])
high=mid-1;
}
return -1;
}
int main()
{
int a[20],i,n,key,pos;

printf("enter n value");
scanf("%d",&n);
printf("enter %d elements",n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("enter the key element");
scanf("%d",&key);
pos=binarysearch(a,0,n-1,key);
if(pos>=0)
{
printf("element is found at %d",pos+1);
}
else
{
printf("element is not found");
}
getch();
}

Result:
Thus the C program for recursive and non recursive binary search was written and executed
successfully

Exp.No :
Date :
Divide and Conquer-Strassen’s Matrix Multiplication
Aim :
To implement Divide and Conquer-Strassen’s Matrix Multiplication
Algorithm
1.Given two matrices A and B, of size n x n, we divide each matrix into four equal-sized
submatrices, each of size n/2 x n/2.
2.We then define seven intermediate matrices:
P1 = A11 * (B12 - B22)
P2 = (A11 + A12) * B22
P3 = (A21 + A22) * B11
P4 = A22 * (B21 - B11)
P5 = (A11 + A22) * (B11 + B22)
P6 = (A12 - A22) * (B21 + B22)
P7 = (A11 - A21) * (B11 + B12)
3.Next, we recursively compute seven products of these submatrices, i.e., P1, P2, P3, P4, P5,
P6, and P7.
4.Finally, we combine the results to obtain the four submatrices of the resulting matrix C of
size n x n:
C11 = P5 + P4 - P2 + P6
C12 = P1 + P2
C21 = P3 + P4
C22 = P5 + P1 - P3 - P7
5.Concatenate the four submatrices C11, C12, C21, and C22 to obtain the final result matrix
C.
Source code:
#include<stdio.h>
int main(){
int z[2][2];
int i, j;
int m1, m2, m3, m4 , m5, m6, m7;
int x[2][2] = {
{12, 34},
{22, 10}
};
int y[2][2] = {
{3, 4},
{2, 1}
};
printf("The first matrix is: ");
for(i = 0; i < 2; i++) {
printf("\n");
for(j = 0; j < 2; j++)
printf("%d\t", x[i][j]);
}
printf("\nThe second matrix is: ");
for(i = 0; i < 2; i++) {
printf("\n");
for(j = 0; j < 2; j++)
printf("%d\t", y[i][j]);
}
m1= (x[0][0] + x[1][1]) * (y[0][0] + y[1][1]);
m2= (x[1][0] + x[1][1]) * y[0][0];
m3= x[0][0] * (y[0][1] - y[1][1]);
m4= x[1][1] * (y[1][0] - y[0][0]);
m5= (x[0][0] + x[0][1]) * y[1][1];
m6= (x[1][0] - x[0][0]) * (y[0][0]+y[0][1]);
m7= (x[0][1] - x[1][1]) * (y[1][0]+y[1][1]);
z[0][0] = m1 + m4- m5 + m7;
z[0][1] = m3 + m5;
z[1][0] = m2 + m4;
z[1][1] = m1 - m2 + m3 + m6;
printf("\nProduct achieved using Strassen's algorithm: ");
for(i = 0; i < 2 ; i++) {
printf("\n");
for(j = 0; j < 2; j++)
printf("%d\t", z[i][j]);
}
return 0;
}

Result:
Thus the Divide and Conquer-Strassen’s Matrix Multiplication can be written and executed
successfully.
Exp.No :
Date :
Decrease and Conquer - Topological sorting
Aim:
To implement Decrease and Conquer - Topological sorting
Algorithm:
Here’s a step-by-step algorithm for topological sorting using Depth First Search (DFS):
 Create a graph with n vertices and m-directed edges.
 Initialize a stack and a visited array of size n.
 For each unvisited vertex in the graph, do the following:
o Call the DFS function with the vertex as the parameter.
o In the DFS function, mark the vertex as visited and recursively call the DFS
function for all unvisited neighbors of the vertex.
o Once all the neighbors have been visited, push the vertex onto the stack.
 After all, vertices have been visited, pop elements from the stack and append them to
the output list until the stack is empty.
 The resulting list is the topologically sorted order of the graph.
Source code:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

// Structure to represent a stack


struct Stack {
int data;
struct Stack* next;
};

struct Graph {
int V; // No. of vertices
// Pointer to an array containing adjacency lists
struct List* adj;
};

// Structure to represent a list (adjacency list)


struct List {
int data;
struct List* next;
};

// Create a new node for the stack


struct Stack* createStackNode(int data)
{
struct Stack* newNode
= (struct Stack*)malloc(sizeof(struct Stack));
newNode->data = data;
newNode->next = NULL;
return newNode;
}

// Create a new node for the adjacency list


struct List* createListNode(int data)
{
struct List* newNode
= (struct List*)malloc(sizeof(struct List));
newNode->data = data;
newNode->next = NULL;
return newNode;
}

// Function to initialize a graph with V vertices


struct Graph* createGraph(int V)
{
struct Graph* graph
= (struct Graph*)malloc(sizeof(struct Graph));
graph->V = V;
graph->adj
= (struct List*)malloc(V * sizeof(struct List));
for (int i = 0; i < V; ++i) {
graph->adj[i].next = NULL;
}
return graph;
}

// Function to add an edge to the graph


void addEdge(struct Graph* graph, int v, int w)
{
struct List* newNode = createListNode(w);
newNode->next = graph->adj[v].next;
graph->adj[v].next = newNode;
}

// A recursive function used by topologicalSort


void topologicalSortUtil(struct Graph* graph, int v,
bool visited[],
struct Stack** stack)
{
visited[v] = true;

struct List* current = graph->adj[v].next;


while (current != NULL) {
int adjacentVertex = current->data;
if (!visited[adjacentVertex]) {
topologicalSortUtil(graph, adjacentVertex,
visited, stack);
}
current = current->next;
}

// Push the current vertex to stack which stores the


// result
struct Stack* newNode = createStackNode(v);
newNode->next = *stack;
*stack = newNode;
}

// The function to do Topological Sort. It uses recursive


// topologicalSortUtil
void topologicalSort(struct Graph* graph)
{
struct Stack* stack = NULL;

// Mark all the vertices as not visited


bool* visited = (bool*)malloc(graph->V * sizeof(bool));
for (int i = 0; i < graph->V; ++i) {
visited[i] = false;
}

// Call the recursive helper function to store


// Topological Sort starting from all vertices one by
// one
for (int i = 0; i < graph->V; ++i) {
if (!visited[i]) {
topologicalSortUtil(graph, i, visited, &stack);
}
}

// Print contents of stack


while (stack != NULL) {
printf("%d ", stack->data);
struct Stack* temp = stack;
stack = stack->next;
free(temp);
}
free(visited);
free(graph->adj);
free(graph);
}
int main()
{
// Create a graph given in the above diagram
struct Graph* g = createGraph(6);
addEdge(g, 5, 2);
addEdge(g, 5, 0);
addEdge(g, 4, 0);
addEdge(g, 4, 1);
addEdge(g, 2, 3);
addEdge(g, 3, 1);

printf("Topological Sorting Order: ");


topologicalSort(g);
return 0;
}

Result:
Thus the C program for Decrease and Conquer - Topological sorting was written and
executed successfully

Exp.No. :
Date :
Transform and Conquer- Heap sort
Aim:
To implement heap sort by using transform and conquer method
Algorithm:
1. Convert to a heap: Use the heapify algorithm to convert the array into a heap.
2. Swap and reduce: Swap the root element with the last element of the heap, then
reduce the heap size by 1.
3. Heapify: Apply heapify to the reduced heap to ensure the largest element is at the root
again.
4. Repeat: Repeat steps 2 and 3 until the heap size is greater than 1.
5. Sort: The array will be sorted in ascending order after the last iteration.
Source code:
#include <stdio.h>
// Heapify function
void heapify(int arr[], int n, int i)
{
int temp, maximum, left_index, right_index;

// currently assuming i postion to


// be holding the largest value
maximum = i;

// right child index


right_index = 2 * i + 2;

// left child index


left_index = 2 * i + 1;

// if left index value is grater than the current index


// value
if (left_index < n && arr[left_index] > arr[maximum])
maximum = left_index;

// if right index value is grater than the current index


// value
if (right_index < n && arr[right_index] > arr[maximum])
maximum = right_index;

// checking if we needed swaping the elements or not


if (maximum != i) {
temp = arr[i];
arr[i] = arr[maximum];
arr[maximum] = temp;
heapify(arr, n, maximum);
}
}

// HeapSorting function
void heapsort(int arr[], int n)
{
int i, temp;

// performing heapify on the non leaf nodes so n/2 - 1


// to 0 are the non leaf nodes
for (i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
// the current array is changed to max heap

for (i = n - 1; i > 0; i--) {


temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}
// Driver code
int main()
{
// initializing the array
int arr[] = { 20, 18, 5, 15, 3, 2 };
int n = 6;

// Displaying original array


printf("Original Array : ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}

printf("\n");
heapsort(arr, n);

// Displaying sorted array


printf("Array after performing heap sort: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}

Result:
Thus, the c program for heap sort by using transform and conquer method was verified and
executed successfully.
Exp.No:
Date:
Dynamic Programming – coin change problem
Aim:
To implement coin change problem by using dynamic programming
Algorithm
 Initialize a new array for dynamicprog of length n+1, where n is the number of
different coin changes you want to find.
 Because there is only one way to give change for 0 dollars, set dynamicprog[0] to 1.
 Iterate through the array for each coin change available and add the value of
dynamicprog[index-coins[i]] to dynamicprog[index] for indexes ranging from '1' to
'n'.
 dynamicprog[n] return value
Source code:
#include<stdio.h>

int count( int S[], int m, int n )


{
int i, j, x, y;

// We need n+1 rows as the table is constructed


// in bottom up manner using the base case 0
// value case (n = 0)
int table[n+1][m];

// Fill the entries for 0 value case (n = 0)


for (i=0; i<m; i++)
table[0][i] = 1;

// Fill rest of the table entries in bottom


// up manner
for (i = 1; i < n+1; i++)
{
for (j = 0; j < m; j++)
{
// Count of solutions including S[j]
x = (i-S[j] >= 0)? table[i - S[j]][j]: 0;

// Count of solutions excluding S[j]


y = (j >= 1)? table[i][j-1]: 0;

// total count
table[i][j] = x + y;
}
}
return table[n][m-1];
}

// Driver program to test above function


int main()
{
int arr[] = {1, 2, 3};
int m = sizeof(arr)/sizeof(arr[0]);
int n = 4;
printf(" %d ", count(arr, m, n));
return 0;
}

Result:
Thus, the c program for coin change problem was verified and executed successfuly
Exp.No:
Date:
Dynamic programming- warshall’s and floyd’s algorithms
Aim:
To implement warshall’s and Floyd’s algorithms by using dynamic programming
Algorithm
Step 1 − Construct an adjacency matrix A with all the costs of edges present in the graph. If
there is no path between two vertices, mark the value as ∞.
Step 2 − Derive another adjacency matrix A1 from A keeping the first row and first column
of the original adjacency matrix intact in A1. And for the remaining values, say A1[i,j],
if A[i,j]>A[i,k]+A[k,j] then replace A1[i,j] with A[i,k]+A[k,j]. Otherwise, do not change the
values. Here, in this step, k = 1 (first vertex acting as pivot).
Step 3 − Repeat Step 2 for all the vertices in the graph by changing the k value for every
pivot vertex until the final matrix is achieved.
Step 4 − The final adjacency matrix obtained is the final solution with all the shortest paths.
Source code:
#include <stdio.h>
void floyds(int b[3][3]) {
int i, j, k;
for (k = 0; k < 3; k++) {
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if ((b[i][k] * b[k][j] != 0) && (i != j)) {
if ((b[i][k] + b[k][j] < b[i][j]) || (b[i][j] == 0)) {
b[i][j] = b[i][k] + b[k][j];
}
}
}
}
}
for (i = 0; i < 3; i++) {
printf("Minimum Cost With Respect to Node: %d\n", i);
for (j = 0; j < 3; j++) {
printf("%d\t", b[i][j]);
}
}
}

int main() {
int b[3][3] = {0};
b[0][1] = 10;
b[1][2] = 15;
b[2][0] = 12;
floyds(b);
return 0;

Result:
Thus, the c program for warshall’s and Floyd’s algorithms by using dynamic programming
was verified and executed successfully.
Exp.No:
Date :
Dynamic programming – Knapsack problem
Aim:
To implement knapsack problem by using dynamic programming
Algorithm:
 Create a 2D array dp of size (n+1)x(w+1), where dp[i][j] will store the maximum
result for i items and j capacity of the knapsack.
 Initialize the dp[0][j] and dp[i][0] with 0 as the maximum profit will be 0 when either
there are no items or the capacity of the knapsack is zero.
 For each item i from 1 to n and for each capacity w from 1 to j.
o If the weight of the current item wt[i-1] is less than or equal to w, then:
o dp[i][w] = max(val[i-1] + dp[i-1][w - wt[i-1]], dp[i-1][j])
o Otherwise, if the weight of the current item is more than w, then:
o dp[i][j] = dp[i-1][j] (same value as without considering the current
item)
 Return the value of dp[n][w] that will contain the maximum value that can be
achieved with the full capacity W using all n items.
Source code:
#include<stdio.h>
int max(int a, int b) {
if(a>b){
return a;
} else {
return b;
}
}
int knapsack(int W, int wt[], int val[], int n) {
int i, w;
int knap[n+1][W+1];
for (i = 0; i <= n; i++) {
for (w = 0; w <= W; w++) {
if (i==0 || w==0)
knap[i][w] = 0;
else if (wt[i-1] <= w)
knap[i][w] = max(val[i-1] + knap[i-1][w-wt[i-1]], knap[i-1][w]);
else
knap[i][w] = knap[i-1][w];
}
}
return knap[n][W];
}
int main() {
int val[] = {20, 25, 40};
int wt[] = {25, 20, 30};
int W = 50;
int n = sizeof(val)/sizeof(val[0]);
printf("The solution is : %d", knapsack(W, wt, val, n));
return 0;
}

Result:
Thus, the c program for knapsack problem by using dynamic programming was verified and
executed successfully.
Exp.No:
Date :
Greedy Technique – Dijkstra’s algorithm
Aim:
To implement dijkstra’s algorithm by using greedy technique
Algorithm
Step 1 : Create a set shortPath to store vertices that come in the way of the shortest path tree.
Step 2 : Initialize all distance values as INFINITE and assign distance values as 0 for source
vertex so that it is picked first.
Step 3 : Loop until all vertices of the graph are in the shortPath.
Step 3.1 : Take a new vertex that is not visited and is nearest.
Step 3.2 : Add this vertex to shortPath.
Step 3.3 : For all adjacent vertices of this vertex update distances. Now check every
adjacent vertex of V, if sum of distance of u and weight of edge is elss the update it.
Source code:
#include <limits.h>
#include <stdio.h>
#define V 9
int minDistance(int dist[], bool sptSet[]) {
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++)
if (sptSet[v] == false && dist[v] <= min)
min = dist[v], min_index = v;
return min_index;
}
int printSolution(int dist[], int n) {
printf("Vertex Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d \t %d\n", i, dist[i]);
return 0;
}
void dijkstra(int graph[V][V], int src) {
int dist[V];
bool sptSet[V];
for (int i = 0; i < V; i++)
dist[i] = INT_MAX, sptSet[i] = false;
dist[src] = 0;
for (int count = 0; count < V - 1; count++) {
int u = minDistance(dist, sptSet);
sptSet[u] = true;
for (int v = 0; v < V; v++)
if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] <
dist[v]) dist[v] = dist[u] + graph[u][v];
}
printSolution(dist, V);
}
int main() {
int graph[V][V] = { { 0, 6, 0, 0, 0, 0, 0, 8, 0 },
{ 6, 0, 8, 0, 0, 0, 0, 13, 0 },
{ 0, 8, 0, 7, 0, 6, 0, 0, 2 },
{ 0, 0, 7, 0, 9, 14, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 10, 0, 0, 0 },
{ 0, 0, 6, 14, 10, 0, 2, 0, 0 },
{ 0, 0, 0, 0, 0, 2, 0, 1, 6 },
{ 8, 13, 0, 0, 0, 0, 1, 0, 7 },
{ 0, 0, 2, 0, 0, 0, 6, 7, 0 }
};
dijkstra(graph, 0);
return 0;
}

Result:
Thus, the c program for dijkstra’s algorithm by using greedy technique was verified and
executed successfully.
Exp.No:
Date :
Greedy Technique – Huffman trees and codes
Aim:
To implement Huffman trees and codes by using greedy technique
Algorithm
nput is an array of unique characters along with their frequency of occurrences and output is
Huffman Tree.
1. Create a leaf node for each unique character and build a min heap of all leaf nodes
(Min Heap is used as a priority queue. The value of frequency field is used to compare
two nodes in min heap. Initially, the least frequent character is at root)
2. Extract two nodes with the minimum frequency from the min heap.

3. Create a new internal node with a frequency equal to the sum of the two nodes
frequencies. Make the first extracted node as its left child and the other extracted node
as its right child. Add this node to the min heap.
4. Repeat steps#2 and #3 until the heap contains only one node. The remaining node is
the root node and the tree is complete.
Source code
#include <stdio.h>
#include <stdlib.h>

// This constant can be avoided by explicitly


// calculating height of Huffman Tree
#define MAX_TREE_HT 100

// A Huffman tree node


struct MinHeapNode {

// One of the input characters


char data;

// Frequency of the character


unsigned freq;
// Left and right child of this node
struct MinHeapNode *left, *right;
};

// A Min Heap: Collection of


// min-heap (or Huffman tree) nodes
struct MinHeap {

// Current size of min heap


unsigned size;

// capacity of min heap


unsigned capacity;

// Array of minheap node pointers


struct MinHeapNode** array;
};

// A utility function allocate a new


// min heap node with given character
// and frequency of the character
struct MinHeapNode* newNode(char data, unsigned freq)
{
struct MinHeapNode* temp = (struct MinHeapNode*)malloc(
sizeof(struct MinHeapNode));

temp->left = temp->right = NULL;


temp->data = data;
temp->freq = freq;

return temp;
}

// A utility function to create


// a min heap of given capacity
struct MinHeap* createMinHeap(unsigned capacity)

struct MinHeap* minHeap


= (struct MinHeap*)malloc(sizeof(struct MinHeap));

// current size is 0
minHeap->size = 0;

minHeap->capacity = capacity;

minHeap->array = (struct MinHeapNode**)malloc(


minHeap->capacity * sizeof(struct MinHeapNode*));
return minHeap;
}

// A utility function to
// swap two min heap nodes
void swapMinHeapNode(struct MinHeapNode** a,
struct MinHeapNode** b)

struct MinHeapNode* t = *a;


*a = *b;
*b = t;
}
// The standard minHeapify function.
void minHeapify(struct MinHeap* minHeap, int idx)

int smallest = idx;


int left = 2 * idx + 1;
int right = 2 * idx + 2;

if (left < minHeap->size


&& minHeap->array[left]->freq
< minHeap->array[smallest]->freq)
smallest = left;

if (right < minHeap->size


&& minHeap->array[right]->freq
< minHeap->array[smallest]->freq)
smallest = right;

if (smallest != idx) {
swapMinHeapNode(&minHeap->array[smallest],
&minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}

// A utility function to check


// if size of heap is 1 or not
int isSizeOne(struct MinHeap* minHeap)
{
return (minHeap->size == 1);
}

// A standard function to extract


// minimum value node from heap
struct MinHeapNode* extractMin(struct MinHeap* minHeap)

struct MinHeapNode* temp = minHeap->array[0];


minHeap->array[0] = minHeap->array[minHeap->size - 1];

--minHeap->size;
minHeapify(minHeap, 0);

return temp;
}

// A utility function to insert


// a new node to Min Heap
void insertMinHeap(struct MinHeap* minHeap,
struct MinHeapNode* minHeapNode)

++minHeap->size;
int i = minHeap->size - 1;

while (i
&& minHeapNode->freq
< minHeap->array[(i - 1) / 2]->freq) {
minHeap->array[i] = minHeap->array[(i - 1) / 2];
i = (i - 1) / 2;
}

minHeap->array[i] = minHeapNode;
}

// A standard function to build min heap


void buildMinHeap(struct MinHeap* minHeap)

int n = minHeap->size - 1;
int i;

for (i = (n - 1) / 2; i >= 0; --i)


minHeapify(minHeap, i);
}

// A utility function to print an array of size n


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

printf("\n");
}

// Utility function to check if this node is leaf


int isLeaf(struct MinHeapNode* root)
{

return !(root->left) && !(root->right);


}

// Creates a min heap of capacity


// equal to size and inserts all character of
// data[] in min heap. Initially size of
// min heap is equal to capacity
struct MinHeap* createAndBuildMinHeap(char data[],
int freq[], int size)

struct MinHeap* minHeap = createMinHeap(size);

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


minHeap->array[i] = newNode(data[i], freq[i]);

minHeap->size = size;
buildMinHeap(minHeap);

return minHeap;
}

// The main function that builds Huffman tree


struct MinHeapNode* buildHuffmanTree(char data[],
int freq[], int size)

{
struct MinHeapNode *left, *right, *top;
// Step 1: Create a min heap of capacity
// equal to size. Initially, there are
// modes equal to size.
struct MinHeap* minHeap
= createAndBuildMinHeap(data, freq, size);

// Iterate while size of heap doesn't become 1


while (!isSizeOne(minHeap)) {

// Step 2: Extract the two minimum


// freq items from min heap
left = extractMin(minHeap);
right = extractMin(minHeap);

// Step 3: Create a new internal


// node with frequency equal to the
// sum of the two nodes frequencies.
// Make the two extracted node as
// left and right children of this new node.
// Add this node to the min heap
// '$' is a special value for internal nodes, not
// used
top = newNode('$', left->freq + right->freq);

top->left = left;
top->right = right;

insertMinHeap(minHeap, top);
}

// Step 4: The remaining node is the


// root node and the tree is complete.
return extractMin(minHeap);
}

// Prints huffman codes from the root of Huffman Tree.


// It uses arr[] to store codes
void printCodes(struct MinHeapNode* root, int arr[],
int top)

// Assign 0 to left edge and recur


if (root->left) {

arr[top] = 0;
printCodes(root->left, arr, top + 1);
}

// Assign 1 to right edge and recur


if (root->right) {

arr[top] = 1;
printCodes(root->right, arr, top + 1);
}

// If this is a leaf node, then


// it contains one of the input
// characters, print the character
// and its code from arr[]
if (isLeaf(root)) {

printf("%c: ", root->data);


printArr(arr, top);
}
}

// The main function that builds a


// Huffman Tree and print codes by traversing
// the built Huffman Tree
void HuffmanCodes(char data[], int freq[], int size)

{
// Construct Huffman Tree
struct MinHeapNode* root
= buildHuffmanTree(data, freq, size);
int arr[MAX_TREE_HT], top = 0;
printCodes(root, arr, top);
}
int main()
{

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };


int freq[] = { 5, 9, 12, 13, 16, 45 };

int size = sizeof(arr) / sizeof(arr[0]);

HuffmanCodes(arr, freq, size);

return 0;
}

Result:
Thus, the c program for Huffman trees and codes by using greedy technique was verified and
executed successfully.
Exp.No:
Date :
Iterative improvement- simplex method
Aim:
To implement iterative improvement by using simplex method
Algorithm
Simplex Algorithm
1. Start with the initial basis associated with identity matrix.
2. Calculate the relative profits.

For MAX problem-


If all the relative profits are less than or equal to 0, then the current basis is the optimal one.
STOP.
Else continue to 3.

For MIN problem


If all the relative profits are greater than or equal to 0, then the current basis is the optimal
one. STOP.
Else continue to 3.

3. Find the column corresponding to max relative profit. Say column k has the max
Rel. profit. So xk will enter the basis.

4. Perform a min ratio test to determine which variable will leave the basis.
minratiotest:XBr/yrk=min{XBi/yik}minratiotest:XBr/yrk=min{XBi/yik}
Index of the min element i.e 'r' will determine the leaving variable.
The basic variable at index r, will leave the basis.
NOTE: Min ratio test is always performed on positive elements.

5. It's evident that the entered variable will not form an identity matrix, so
we will have to perform row operations to make it identity again.
Find the pivot element. The element at index (r, k) will be the pivot element and
row r will be the pivot row.

6. Divide the rth row by pivot to make it 1. And subtract c*(rth row) from other
rows to make them 0, where c is the coefficient required to make that row 0.
Source code:
#include <stdio.h>
int main() {
int a, b, i, j, k, pc, pr, count;
float pe, min_ratio, ratio, pc_check, store;
printf("Enter number of equations ");
scanf("%d", &a);
printf("Enter number of variables ");
scanf("%d", &b);

float table[a][b];
float rhs[a];
float obj[a];
int row = a + 1;
int col = a + b + 1;
float table2[row][col];

printf("\n\n Enter coefficient of equations \n ");


for (i = 1; i <= a; i++) {
printf("\n For ROW %d\n ", i);
for (j = 1; j <= b; j++) {
printf("\t\tEnter the coefficient X%d%d: ", i, j);
scanf("%f", &table[i][j]);
}
printf("\t\tEnter the coefficient of RHS%d: ", i);
scanf("%f", &rhs[i]);
}

printf("\n Enter coefficients of the objective function\n");


for (j = 1; j <= b; j++) {
printf("\t\tEnter the coefficient X%d%d: ", i, j);
scanf("%f", &obj[j]);
}

for (i = 1; i < row; i++) {


for (j = 1; j <= col; j++) {
if (j <= b) {
table2[i][j] = table[i][j];
}
if (j > b) {
if (j == b + i) {
table2[i][j] = 1.0;
} else {
table2[i][j] = 0.0;
}
}
if (j == col) {
table2[i][col] = rhs[i];
}
}
}
for (j = 1; j <= col; j++) {
if (j <= b) {
table2[row][j] = -obj[j];
}
if (j > b) {
table2[row][j]

= 0.0;
}
}

while (1) {
for (k = 1; k <= col; k++) {
printf("\n Iteration %d \n ", k - 1);
for (j = 1; j < col; j++) {
printf("\t X%d", j);
}
printf("\t RHS \n");
for (i = 1; i <= row; i++) {
for (j = 1; j <= col; j++) {
printf("\t%0.2f", table2[i][j]);
}
printf("\n");
}

pc = 1, pc_check = 0, count = 0;
for (j = 1; j <= col; j++) {
if (table2[row][j] < 0) {
if (pc_check > table2[row][j]) {
pc_check = table2[row][j];
pc = j;
count = 1;
}
}
if (j == col && count == 0) {
goto okay;
}
}

pr = 0, pe = 1, min_ratio = 1;
for (i = 1; i <= a; i++) {
if (table2[i][pc] > 0) {
ratio = table2[i][col] / table2[i][pc];
if (pr == 0) {
min_ratio = table2[i][col] / table2[i][pc];
count++;
pe = table2[i][pc];
pr = i;
}
if (min_ratio >= ratio && pr != 0) {
if (min_ratio == ratio) {
if (table2[i][pc] < pe) {
pe = table2[i][pc];
pr = i;
}
} else {
min_ratio = ratio;
pr = i;
pe = table2[i][pc];
}
}
}
if (table2[i][pc] < 0 && i == a) {
printf("\n\tUnbounded solution\n");
return 0;
}
}

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


table2[pr][j] = table2[pr][j] / pe;
}
for (i = 1; i <= row; i++) {
float pcoff = table2[i][pc];
for (j = 1; j <= col; j++) {
if (i != pr) {
table2[i][j] = table2[i][j] - (table2[pr][j]) * pcoff;
}
}
}
}
}
okay:
for (i = 0; i <= row; i++) {
for (j = 0; j <= b; j++) {
if (table2[i][j] == 1) {
printf(" \t For X%d == %0.3f , ", j, table2[i][col]);
}
}
}
printf("The optimum value is %0.3f\n ", table2[row][col]);
return 0;
}

Result:
Thus, the c program of iterative improvement for simplex method was written and executed
successfully.
Exp.No:
Date :
Backtracking- N-Queen problem
Aim:
To implement N-Queen problem by using backtracking.
Algorithm
 Place the first queen in the top-left cell of the chessboard.
 After placing a queen in the first cell, mark the position as a part of the solution and
then recursively check if this will lead to a solution.
 Now, if placing the queen doesn’t lead to a solution. Then go to the first step and
place queens in other cells. Repeat until all cells are tried.
 If placing queen returns a lead to solution return TRUE.
 If all queens are placed return TRUE.
 If all rows are tried and no solution is found, return FALSE.
Source code:
#include<stdio.h>
#define BOARD_SIZE 5
void displayChess(int chBoard[BOARD_SIZE][BOARD_SIZE]) {
for (int row = 0; row < BOARD_SIZE; row++) {
for (int col = 0; col < BOARD_SIZE; col++)
printf("%d ", chBoard[row][col]);
printf("\n");
}
}
int isQueenPlaceValid(int chBoard[BOARD_SIZE][BOARD_SIZE], int crntRow, int
crntCol) {
// checking if queen is in the left or not
for (int i = 0; i < crntCol; i++)
if (chBoard[crntRow][i])
return 0;
for (int i = crntRow, j = crntCol; i >= 0 && j >= 0; i--, j--)
//checking if queen is in the left upper diagonal or not
if (chBoard[i][j])
return 0;
for (int i = crntRow, j = crntCol; j >= 0 && i < BOARD_SIZE; i++, j--)
//checking if queen is in the left lower diagonal or not
if (chBoard[i][j])
return 0;
return 1;
}
int solveProblem(int chBoard[BOARD_SIZE][BOARD_SIZE], int crntCol) {
//when N queens are placed successfully
if (crntCol >= BOARD_SIZE)
return 1;
// checking placement of queen is possible or not
for (int i = 0; i < BOARD_SIZE; i++) {
if (isQueenPlaceValid(chBoard, i, crntCol)) {
//if validate, place the queen at place (i, col)
chBoard[i][crntCol] = 1;
//Go for the other columns recursively
if (solveProblem(chBoard, crntCol + 1))
return 1;
//When no place is vacant remove that queen
chBoard[i][crntCol] = 0;
}
}
return 0;
}
int displaySolution() {
int chBoard[BOARD_SIZE][BOARD_SIZE];
for(int i = 0; i < BOARD_SIZE; i++)
for(int j = 0; j < BOARD_SIZE; j++)
//set all elements to 0
chBoard[i][j] = 0;
//starting from 0th column
if (solveProblem(chBoard, 0) == 0) {
printf("Solution does not exist");
return 0;
}
displayChess(chBoard);
return 1;
}
int main() {
displaySolution();
return 0;
}

Result:
Thus, the c program N-Queen problem by using backtracking was verified and executed
successfully.
Exp.No:
Date :
Backtracking- subset sum problem
Aim:
To implement subset sum problem by using backtracking
Algorithm
Here's how the backtracking algorithm works for the subset sum problem:
 Build a solution: Start with a solution, and then build it piece by piece.

 Backtrack: If a piece doesn't fit, backtrack. For example, if the target sum is 5 and
the current subset is {2, 3}, backtrack if the sum is over 5.

 Terminate: When a subset's sum equals the desired sum, terminate.


Source code:
#include <stdio.h>
#include <stdlib.h>
static int total_nodes;
void printValues(int A[], int size){
for (int i = 0; i < size; i++) {
printf("%*d", 5, A[i]);
}
printf("\n");
}
void subset_sum(int s[], int t[], int s_size, int t_size, int sum, int ite, int const target_sum){
total_nodes++;
if (target_sum == sum) {
printValues(t, t_size);
subset_sum(s, t, s_size, t_size - 1, sum - s[ite], ite + 1, target_sum);
return;
}
else {
for (int i = ite; i < s_size; i++) {
t[t_size] = s[i];
subset_sum(s, t, s_size, t_size + 1, sum + s[i], i + 1, target_sum);
}
}
}
void generateSubsets(int s[], int size, int target_sum){
int* tuplet_vector = (int*)malloc(size * sizeof(int));
subset_sum(s, tuplet_vector, size, 0, 0, 0, target_sum);
free(tuplet_vector);
}
int main(){
int set[] = { 5, 6, 12 , 54, 2 , 20 , 15 };
int size = sizeof(set) / sizeof(set[0]);
printf("The set is ");
printValues(set , size);
generateSubsets(set, size, 25);
printf("Total Nodes generated %d\n", total_nodes);
return 0;
}

Result:
Thus, the c program for subset sum problem by using backtracking.
Exp.No:
Date :
Branch and bound – traveling salesman problem
Aim:
To implement traveling salesman problem by using Branch and bound technique
Algorithm
Here are some steps for the branch and bound algorithm for the TSP:
 Create a child node and assign it the next available node number
 Label the child node with the two links that correspond to the zeroes in the
opportunity matrix
 Compute regrets
 Choose the largest regret, and call it Rmax
Source code:
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>

#define MAX 10

int n; // Number of cities


int tspPath[MAX + 1]; // Stores the final path
int finalCost = INT_MAX; // Stores the minimum cost

// Function to print the path


void printPath(int path[]) {
for (int i = 0; i < n; i++) {
printf("%d -> ", path[i]);
}
printf("%d\n", path[0]);
}

// Function to calculate the minimum edge cost from a given city


int findMinEdge(int cost[MAX][MAX], int city) {
int min = INT_MAX;
for (int i = 0; i < n; i++) {
if (cost[city][i] < min && city != i) {
min = cost[city][i];
}
}
return min;
}

// Function to calculate the second minimum edge cost from a given city
int findSecondMinEdge(int cost[MAX][MAX], int city) {
int first = INT_MAX, second = INT_MAX;
for (int i = 0; i < n; i++) {
if (city == i) continue;
if (cost[city][i] <= first) {
second = first;
first = cost[city][i];
} else if (cost[city][i] < second) {
second = cost[city][i];
}
}
return second;
}

// Recursive function to solve TSP using Branch and Bound


void tspBranchBound(int cost[MAX][MAX], bool visited[], int currBound, int currCost, int
level, int path[]) {
// If we have reached the last level, update the minimum cost and path
if (level == n) {
if (cost[path[level - 1]][path[0]] != 0) {
int totalCost = currCost + cost[path[level - 1]][path[0]];
if (totalCost < finalCost) {
for (int i = 0; i < n; i++) {
tspPath[i] = path[i];
}
tspPath[n] = path[0];
finalCost = totalCost;
}
}
return;
}

// Try all next cities


for (int i = 0; i < n; i++) {
if (!visited[i] && cost[path[level - 1]][i] != 0) {
int tempBound = currBound;
currCost += cost[path[level - 1]][i];

// Calculate the new bound


if (level == 1) {
currBound -= (findMinEdge(cost, path[level - 1]) + findMinEdge(cost, i)) / 2;
} else {
currBound -= (findSecondMinEdge(cost, path[level - 1]) + findMinEdge(cost, i)) /
2;
}

// If the current cost + bound is less than the final cost, explore this path
if (currCost + currBound < finalCost) {
path[level] = i;
visited[i] = true;
tspBranchBound(cost, visited, currBound, currCost, level + 1, path);
}
// Backtrack
currCost -= cost[path[level - 1]][i];
currBound = tempBound;
visited[i] = false;
}
}
}

// Function to solve the TSP problem


void solveTSP(int cost[MAX][MAX]) {
bool visited[MAX] = {false};
int path[MAX + 1];
int currBound = 0;

// Initialize the current bound


for (int i = 0; i < n; i++) {
currBound += (findMinEdge(cost, i) + findSecondMinEdge(cost, i));
}
currBound = (currBound & 1) ? currBound / 2 + 1 : currBound / 2;

visited[0] = true;
path[0] = 0;

// Start the Branch and Bound algorithm


tspBranchBound(cost, visited, currBound, 0, 1, path);

// Print the result


printf("Minimum cost: %d\n", finalCost);
printf("Path: ");
printPath(tspPath);
}
// Main function
int main() {
int cost[MAX][MAX];
printf("Enter the number of cities: ");
scanf("%d", &n);

printf("Enter the cost matrix (enter 0 if there is no direct path):\n");


for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &cost[i][j]);
}
}

solveTSP(cost);

return 0;
}

Result:
Thus, the c program traveling salesman problem by using Branch and bound technique was
verified and executed successfully.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy