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

DAA Lab Assignment 1

The document contains algorithms and C code implementations for two greedy algorithms: Fractional Knapsack and Huffman Coding. It also outlines the aim, algorithm, and code structure for Matrix Chain Multiplication using dynamic programming. Test cases are run and results shown for the greedy algorithms. The document is for a lab assignment on data structures and algorithms.

Uploaded by

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

DAA Lab Assignment 1

The document contains algorithms and C code implementations for two greedy algorithms: Fractional Knapsack and Huffman Coding. It also outlines the aim, algorithm, and code structure for Matrix Chain Multiplication using dynamic programming. Test cases are run and results shown for the greedy algorithms. The document is for a lab assignment on data structures and algorithms.

Uploaded by

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

LAB Assignment - 1

Name: Atharva Honrao


Registration No: 21BDS0135
Course Title: DAA Lab
Faculty: Ebenezer Juliet
Greedy Strategy

A] Fractional Knapsack
Aim:
To write the algorithm, code, screenshot, test cases (2) and the
result of the Fractional Knapsack Problem using Greedy Strategy
C Language.

Algorithm:
Greedy-Fractional-Knapsack (w[1..n], p[1..n], W)
for i = 1 to n
do x[i] = 0
weight = 0
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

Code:
#include<stdio.h>

int n=4;

int c[10]={10,40,20,24};//weight

int v[10]={100,280,120,120};//profit
int W = 60;

void simple_fill() {
int cur_w;
float tot_v;
int i, maxi;
int used[10];

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


used[i] = 0;

cur_w = W;
while (cur_w > 0) {
maxi = -1;
for (i = 0; i < n; ++i)
if ((used[i] == 0) &&
((maxi == -1) || ((float)v[i]/c[i] >(float)v[maxi]/c[maxi])))
maxi = i;
used[maxi] = 1;
cur_w -= c[maxi];
tot_v += v[maxi];
if (cur_w >= 0)
printf("Added object %d (%d$, %dKg) completely in the bag. Space
left: %d.\n", maxi + 1, v[maxi], c[maxi], cur_w);
else {
printf("Added %d%% (%d$, %dKg) of object %d in the bag.\n",
(int)((1 + (float)cur_w/c[maxi]) * 100), v[maxi], c[maxi], maxi + 1);
tot_v -= v[maxi];
tot_v += (1 + (float)cur_w/c[maxi]) * v[maxi];
}
}

printf("Filled the bag with objects worth %.2f$.\n", tot_v);


}

int main(int argc, char *argv[]) {


simple_fill();
return 0;
}
Program:

Execution:
Result:
Thus, we successfully verified and drove output using Fractional
Knapsack Problem using Greedy Strategy C Language.
B] Huffman Coding
Aim:
To write the algorithm, code, screenshot, test cases (2) and the
result of the Huffman Coding using Greedy Strategy C Language.

Algorithm:
Procedure Huffman(C): // C is the set of n characters and related information
n = C.size
Q = priority_queue()
for i = 1 to n
n = node(C[i])
Q.push(n)
end for
while Q.size() is not equal to 1
Z = new node()
Z.left = x = Q.pop
Z.right = y = Q.pop
Z.frequency = x.frequency + y.frequency
Q.push(Z)
end while
Return Q

Code:
// C program for Huffman Coding
#include <stdio.h>
#include <stdlib.h>
#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;
};

// 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
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);

// Print Huffman codes using


// the Huffman tree built above
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;
}

Program:
Execution:

Test Case 1:

Test Case :
Result:
Thus, we successfully verified and drove output using Huffman
Coding using Greedy Strategy C Language.

Dynamic Programming

A] Matrix Chain Multiplication

Aim:
To write the algorithm, code, screenshot, test cases (2) and the
result of the Matrix Chain Multiplication using Dynamic
Programming C Language.

Algorithm:
Begin
define table minMul of size n x n, initially fill with all 0s
for length := 2 to n, do
fir i:=1 to n-length, do
j := i + length – 1
minMul[i, j] := ∞
for k := i to j-1, do
q := minMul[i, k] + minMul[k+1, j] + array[i-1]*array[k]*array[j]
if q < minMul[i, j], then minMul[i, j] := q
done
done
done
return minMul[1, n-1]
End
Code:
#include <stdio.h>
#include<limits.h>
#define INFY 999999999
long int m[20][20];
int s[20][20];
int p[20],i,j,n;

void print_optimal(int i,int j)


{
if (i == j)
printf(" A%d ",i);
else
{
printf("( ");
print_optimal(i, s[i][j]);
print_optimal(s[i][j] + 1, j);
printf(" )");
}
}

void matmultiply(void)
{
long int q;
int k;
for(i=n;i>0;i--)
{
for(j=i;j<=n;j++)
{
if(i==j)
m[i][j]=0;
else
{
for(k=i;k<j;k++)
{
q=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(q<m[i][j])
{
m[i][j]=q;
s[i][j]=k;
}
}
}
}
}
}

int MatrixChainOrder(int p[], int i, int j)


{
if(i == j)
return 0;
int k;
int min = INT_MAX;
int count;

for (k = i; k <j; k++)


{
count = MatrixChainOrder(p, i, k) +
MatrixChainOrder(p, k+1, j) +
p[i-1]*p[k]*p[j];

if (count < min)


min = count;
}

// Return minimum count


return min;
}

void main()
{
int k;
printf("Enter the no. of elements: ");
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
{
m[i][i]=0;
m[i][j]=INFY;
s[i][j]=0;
}
printf("\nEnter the dimensions: \n");
for(k=0;k<=n;k++)
{
printf("P%d: ",k);
scanf("%d",&p[k]);
}
matmultiply();
printf("\nCost Matrix M:\n");
for(i=1;i<=n;i++)
for(j=i;j<=n;j++)
printf("m[%d][%d]: %ld\n",i,j,m[i][j]);

i=1,j=n;
printf("\nMultiplication Sequence : ");
print_optimal(i,j);
printf("\nMinimum number of multiplications is : %d ",
MatrixChainOrder(p, 1, n));

}
Program:
Execution:
Test Case 1:

Test Case: 2
Result:
Thus, we successfully verified and drove output using Matrix
Chain Multiplication using Dynamic Programming C Language.

B] Longest Common Subsequence

Aim:
To write the algorithm, code, screenshot, test cases (2) and the
result of the Longest Common Subsequence using Dynamic
Programming C Language.

Algorithm:

X and Y be two given sequences


Initialize a table LCS of dimension X.length * Y.length
X.label = X
Y.label = Y
LCS[0][] = 0
LCS[][0] = 0
Start from LCS[1][1]
Compare X[i] and Y[j]
If X[i] = Y[j]
LCS[i][j] = 1 + LCS[i-1, j-1]
Point an arrow to LCS[i][j]
Else
LCS[i][j] = max(LCS[i-1][j], LCS[i][j-1])
Point an arrow to max(LCS[i-1][j], LCS[i][j-1])
Code:
#include<stdio.h>
#include<string.h>

int max(int a, int b);


void findLCS(char *X, char *Y, int XLen, int YLen);

int max(int a, int b) {


return (a > b)? a : b;
}

void findLCS(char *X, char *Y, int XLen, int YLen) {


int L[XLen + 1][YLen + 1];
int r, c, i;

/*
* find the length of the LCS
*/
for(r = 0; r <= XLen; r++) {

for(c = 0; c <= YLen; c++) {

if(r == 0 || c == 0) {

L[r][c] = 0;

} else if(X[r - 1] == Y[c - 1]) {

L[r][c] = L[r - 1][c - 1] + 1;

} else {

L[r][c] = max(L[r - 1][c], L[r][c - 1]);


}
}
}

/*
* Print LCS
*/
r = XLen;
c = YLen;
i = L[r][c];

char LCS[i+1];

/*
* setting the NULL character at the end of LCS character array.
* as we know in C programming language, NULL character is used
* to denote the end of a string
*/
LCS[i] = '\0';

while(r > 0 && c > 0) {

if(X[r - 1] == Y[c - 1]) {

LCS[i - 1] = X[r - 1];

i--;
r--;
c--;

} else if(L[r - 1][c] > L[r][c - 1]) {

r--;

} else {

c--;

//print result
printf("Length of the LCS: %d\n", L[XLen][YLen]);
printf("LCS: %s\n", LCS);
int q,w;
for (q=0;q<YLen;q++)
{
for (w=0;w<XLen;w++)
{
printf("%d ",L[q][w]);
}
printf ("\n");
}
}

int main(void) {
//the two sequences
char X[] = "ABCF";
char Y[] = "ABCDEF";

//length of the sequences


int XLen = strlen(X);
int YLen = strlen(Y);

findLCS(X, Y, XLen, YLen);

return 0;
}
Program:
Execution:

Test Case 1:
Test Case 2:

Result:
Thus, we successfully verified and drove output using Longest
Common Subsequence using Dynamic Programming C Language.
Divide And Conquer

A] Maximum Subarray

Aim:
To write the algorithm, code, screenshot, test cases (2) and the
result of the Maximum Subarray using Divide and Conquer C
Language.

Algorithm:
int maxSubarraySum ( int A [] , int n)
{
int max_sum = 0
for(i = 0 to n-1)
{
for(j = i to n-1)
{
int sum = 0
for(k = i to j)
sum = sum + A[k]
if(sum > max_sum)
max_sum = sum
}
}
return max_sum
}

Code:
#include <stdio.h>
#include <limits.h>
// Utility function to find the maximum of two numbers
int max(int x, int y) {
return (x > y) ? x : y;
}

// Function to find the maximum subarray sum using divide-and-conquer


int maximum_sum(int nums[], int low, int high)
{
// If the array contains 0 or 1 element
if (high <= low) {
return nums[low];
}

// Find the middle array element


int mid = (low + high) / 2;

// Find maximum subarray sum for the left subarray,


// including the middle element
int left_max = INT_MIN;
int sum = 0;
for (int i = mid; i >= low; i--)
{
sum += nums[i];
if (sum > left_max) {
left_max = sum;
}
}

// Find maximum subarray sum for the right subarray,


// excluding the middle element
int right_max = INT_MIN;
sum = 0; // reset sum to 0
for (int i = mid + 1; i <= high; i++)
{
sum += nums[i];
if (sum > right_max) {
right_max = sum;
}
}
// Recursively find the maximum subarray sum for the left
// and right subarray, and take maximum
int max_left_right = max(maximum_sum(nums, low, mid),
maximum_sum(nums, mid + 1, high));

// return the maximum of the three


return max(max_left_right, left_max + right_max);
}

int main(void)
{
int arr[] = { 2, -4, 1, 9, -6, 7, -3 };
int n = sizeof(arr) / sizeof(arr[0]);

printf("The maximum sum of the subarray is %d",


maximum_sum(arr, 0, n - 1));

return 0;
}

Program:
Execution:

Test Case 1:
Test Case 2:

Result:
Thus, we successfully verified and drove output using Maximum
Subarray using Divide and Conquer C Language.
B] Karatsuba faster integer multiplication

Aim:
To write the algorithm, code, screenshot, test cases (2) and the
result of the Karatsuba faster integer multiplication using Divide
and Conquer C Language.

Algorithm:

procedure karatsuba(num1, num2)


if (num1 < 10) or (num2 < 10)
return num1*num2

*calculates the size of the numbers*


m = max(size_base10(num1), size_base10(num2))
m2 = m/2

*split the digit sequences about the middle*


high1, low1 = split_at(num1, m2)
high2, low2 = split_at(num2, m2)

*3 calls made to numbers approximately half the size*


z0 = karatsuba(low1, low2)
z1 = karatsuba((low1 + high1), (low2 + high2))
z2 = karatsuba(high1, high2)
return (z2 * 10 ^ (2 * m2)) + ((z1 - z2 - z0) * 10 ^ (m2)) + (z0)
Code:
// C++ implementation of Karatsuba algorithm for bit string multiplication.
#include<iostream>
#include<stdio.h>

using namespace std;

int makeEqualLength(string &str1, string &str2)


{
int len1 = str1.size();
int len2 = str2.size();
if (len1 < len2)
{
for (int i = 0 ; i < len2 - len1 ; i++)
str1 = '0' + str1;
return len2;
}
else if (len1 > len2)
{
for (int i = 0 ; i < len1 - len2 ; i++)
str2 = '0' + str2;
}
return len1; // If len1 >= len2
}

// The main function that adds two bit sequences and returns the addition
string addBitStrings( string first, string second )
{
string result; // To store the sum bits

// make the lengths same before adding


int length = makeEqualLength(first, second);
int carry = 0; // Initialize carry

// Add all bits one by one


for (int i = length-1 ; i >= 0 ; i--)
{
int firstBit = first.at(i) - '0';
int secondBit = second.at(i) - '0';
// boolean expression for sum of 3 bits
int sum = (firstBit ^ secondBit ^ carry)+'0';

result = (char)sum + result;

// boolean expression for 3-bit addition


carry = (firstBit&secondBit) | (secondBit&carry) | (firstBit&carry);
}

// if overflow, then add a leading 1


if (carry) result = '1' + result;

return result;
}

// A utility function to multiply single bits of strings a and b


int multiplyiSingleBit(string a, string b)
{ return (a[0] - '0')*(b[0] - '0'); }

// The main function that multiplies two bit strings X and Y and returns
// result as long integer
long int multiply(string X, string Y)
{
// Find the maximum of lengths of x and Y and make length
// of smaller string same as that of larger string
int n = makeEqualLength(X, Y);

// Base cases
if (n == 0) return 0;
if (n == 1) return multiplyiSingleBit(X, Y);

int fh = n/2; // First half of string, floor(n/2)


int sh = (n-fh); // Second half of string, ceil(n/2)

// Find the first half and second half of first string.


// Refer http://goo.gl/lLmgn for substr method
string Xl = X.substr(0, fh);
string Xr = X.substr(fh, sh);
// Find the first half and second half of second string
string Yl = Y.substr(0, fh);
string Yr = Y.substr(fh, sh);

// Recursively calculate the three products of inputs of size n/2


long int P1 = multiply(Xl, Yl);
long int P2 = multiply(Xr, Yr);
long int P3 = multiply(addBitStrings(Xl, Xr), addBitStrings(Yl, Yr));

// Combine the three products to get the final result.


return P1*(1<<(2*sh)) + (P3 - P1 - P2)*(1<<sh) + P2;
}

// Program to test above functions


int main()
{
printf ("%ld\n", multiply("1100", "1010"));
printf ("%ld\n", multiply("110", "1010"));
printf ("%ld\n", multiply("11", "1010"));
printf ("%ld\n", multiply("1", "1010"));
printf ("%ld\n", multiply("0", "1010"));
printf ("%ld\n", multiply("111", "111"));
printf ("%ld\n", multiply("11", "11"));
}
Program:
Execution:

Result:
Thus, we successfully verified and drove output using Karatsuba
faster integer multiplication using Divide and Conquer C
Language.

You might also like