0% found this document useful (0 votes)
12 views55 pages

Ads Lab Manual

The document contains C implementations for AVL trees, B-trees, and heaps. It includes code for various operations such as insertion, deletion, and searching for both AVL and B-trees, as well as heap creation and manipulation. Additionally, it outlines the properties and balancing mechanisms of AVL trees and the structure of B-trees.

Uploaded by

ganesh
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)
12 views55 pages

Ads Lab Manual

The document contains C implementations for AVL trees, B-trees, and heaps. It includes code for various operations such as insertion, deletion, and searching for both AVL and B-trees, as well as heap creation and manipulation. Additionally, it outlines the properties and balancing mechanisms of AVL trees and the structure of B-trees.

Uploaded by

ganesh
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/ 55

Exercise – 1

a. write a c program to implement AVL trees and its operations


// AVL tree implementation in C
#include <stdio.h>
#include <stdlib.h>
// Create Node
struct Node {
int key;
struct Node *left;
struct Node *right;
int height;
};
int max(int a, int b);
// Calculate height
int height(struct Node *N) {
if (N == NULL)
return 0;
return N->height;
}
int max(int a, int b) {
return (a > b) ? a : b;
}
// Create a node
struct Node *newNode(int key) {
struct Node *node = (struct Node *)malloc(sizeof(struct Node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1;
return (node);
}
// Right rotate
struct Node *rightRotate(struct Node *y)
{
struct Node *x = y->left;
struct Node *T2 = x->right;
x->right = y;
y->left = T2;
y->height = max(height(y->left), height(y->right)) + 1;
x->height = max(height(x->left), height(x->right)) + 1;
return x;
}
// Left rotate
struct Node *leftRotate(struct Node *x) {
struct Node *y = x->right;
struct Node *T2 = y->left;
y->left = x;
x->right = T2;
x->height = max(height(x->left), height(x->right)) + 1;
y->height = max(height(y->left), height(y->right)) + 1;
return y;
}
// Get the balance factor
int getBalance(struct Node *N) {
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
// Insert node
struct Node *insertNode(struct Node *node, int key) {
// Find the correct position to insertNode the node and insertNode it
if (node == NULL)
return (newNode(key));
if (key < node->key)
node->left = insertNode(node->left, key);
else if (key > node->key)
node->right = insertNode(node->right, key);
else
return node;
// Update the balance factor of each node and
// Balance the tree
node->height = 1 + max(height(node->left),height(node->right));
int balance = getBalance(node);
if (balance > 1 && key < node->left->key)
return rightRotate(node);
if (balance < -1 && key > node->right->key)
return leftRotate(node);
if (balance > 1 && key > node->left->key)
{
node->left = leftRotate(node->left);
return rightRotate(node);
}
if (balance < -1 && key < node->right->key)
{
node->right = rightRotate(node->right);
return leftRotate(node);
}

return node;
}
struct Node *minValueNode(struct Node *node)
{
struct Node *current = node;
while (current->left != NULL)
current = current->left;
return current;
}
// Delete a nodes
struct Node *deleteNode(struct Node *root, int key)
{
// Find the node and delete it
if (root == NULL)
return root;
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else {
if ((root->left == NULL) || (root->right == NULL)) {
struct Node *temp = root->left ? root->left : root->right;
if (temp == NULL)
{
temp = root;
root = NULL;
} else
*root = *temp;
free(temp);
}
else
{
struct Node *temp = minValueNode(root->right);
root->key = temp->key;
root->right = deleteNode(root->right, temp->key);
}
}
if (root == NULL)
return root;
// Update the balance factor of each node and
// balance the tree
root->height = 1 + max(height(root->left),
height(root->right));
int balance = getBalance(root);
if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);
if (balance > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}
if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);
if (balance < -1 && getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
// Print the tree
void printPreOrder(struct Node *root)
{
if (root != NULL) {
printf("%d ", root->key);
printPreOrder(root->left);
printPreOrder(root->right);
}
}
int main() {
struct Node *root = NULL;
root = insertNode(root, 2);
root = insertNode(root, 1);
root = insertNode(root, 7);
root = insertNode(root, 4);
root = insertNode(root, 5);
root = insertNode(root, 3);
root = insertNode(root, 8);
printPreOrder(root);
root = deleteNode(root, 3);
printf("\nAfter deletion: ");
printPreOrder(root);
return 0;
}
b. Develop a solution to the given problem using AVL Trees.
21,26,30,9,4,14,28,18,15,10,2,3,7
AVL Tree
 AVL Trees are Self-Balanced Binary Search Trees.
 In AVL trees, the balancing factor of each node is either 0 or 1 or -1.
 Balance Factor of AVL Tree calculated as = Height of Left Sub-tree - Height of Right Sub-tree
Construction of AVL Trees -
 Insertion Operation is performed to construct the AVL Tree.
 Inserting the element in the AVL tree is same as the insertion performed in BST.
 After insertion, check the balance factor of each node of the resulting tree.
o After the insertion, the balance factor of each node is either 0 or 1 or -1, then the tree
is considered to be balanced, concludes the operation, and inserts the next element if
any.
o After the insertion, the balance factor of at least one node is not 0 or 1 or -1, then the
tree is considered to be imbalanced, perform the suitable rotation to balance the
tree, and after the tree is balanced, insert the next element if any.
Rotations used to Balance the AVL Tree -
 After inserting an element in the AVL tree,
 If a tree becomes imbalanced, then there exists one particular node in the tree by balancing
which the entire tree becomes balanced automatically.
 To rebalance the tree, balance that particular node.
To find that particular node:
 Traverse the path from the newly inserted node to the root node.
 Check the balance factor of each node that is encountered while traversing the path.
 The first encountered imbalanced node will be the node that needs to be balanced.
To balance that node:
 Count three nodes in the direction of the leaf node.
 Then, use the concept of AVL Tree Rotations to rebalance the tree.
o LL Rotation - In LL rotation, every node moves one position to left from the current
position.
o RR Rotation - In RR rotation, every node moves one position to right from the current
position.
o LR Rotation - In LR rotation, at first, every node moves one position to the left and then
one position to right from the current position.
o RL Rotation - In RL rotation, at first every node moves one position to right and then
one position to left from the current position.

Step-by-Step Construction of the AVL Tree for the given Sequence 21, 26, 30, 9, 4, 14, 28, 18,15,10,
2, 3, 7
Exercise – 2
a. Implement B- Trees and its operations.
// Searching a key on a B-tree in C
#include <stdio.h>
#include <stdlib.h>
#define MAX 3
#define MIN 2
struct BTreeNode {
int val[MAX + 1], count;
struct BTreeNode *link[MAX + 1];
};
struct BTreeNode *root;
// Create a node
struct BTreeNode *createNode(int val, struct BTreeNode *child) {
struct BTreeNode *newNode;
newNode = (struct BTreeNode *)malloc(sizeof(struct BTreeNode));
newNode->val[1] = val;
newNode->count = 1;
newNode->link[0] = root;
newNode->link[1] = child;
return newNode;
}
// Insert node
void insertNode(int val, int pos, struct BTreeNode *node,
struct BTreeNode *child) {
int j = node->count;
while (j > pos) {
node->val[j + 1] = node->val[j];
node->link[j + 1] = node->link[j];
j--;
}
node->val[j + 1] = val;
node->link[j + 1] = child;
node->count++;
}
// Split node
void splitNode(int val, int *pval, int pos, struct BTreeNode *node,
struct BTreeNode *child, struct BTreeNode **newNode) {
int median, j;
if (pos > MIN)
median = MIN + 1;
else
median = MIN;
*newNode = (struct BTreeNode *)malloc(sizeof(struct BTreeNode));
j = median + 1;
while (j <= MAX) {
(*newNode)->val[j - median] = node->val[j];
(*newNode)->link[j - median] = node->link[j];
j++;
}
node->count = median;
(*newNode)->count = MAX - median;
if (pos <= MIN) {
insertNode(val, pos, node, child);
} else {
insertNode(val, pos - median, *newNode, child);
}
*pval = node->val[node->count];
(*newNode)->link[0] = node->link[node->count];
node->count--;
}
// Set the value
int setValue(int val, int *pval,
struct BTreeNode *node, struct BTreeNode **child) {
int pos;
if (!node) {
*pval = val;
*child = NULL;
return 1;
}
if (val < node->val[1]) {
pos = 0;
} else {
for (pos = node->count;
(val < node->val[pos] && pos > 1); pos--)
;
if (val == node->val[pos]) {
printf("Duplicates are not permitted\n");
return 0;
}
}
if (setValue(val, pval, node->link[pos], child)) {
if (node->count < MAX) {
insertNode(*pval, pos, node, *child);
} else {
splitNode(*pval, pval, pos, node, *child, child);
return 1;
}
}
return 0;
}
// Insert the value
void insert(int val) {
int flag, i;
struct BTreeNode *child;

flag = setValue(val, &i, root, &child);


if (flag)
root = createNode(i, child);
}
// Search node
void search(int val, int *pos, struct BTreeNode *myNode) {
if (!myNode) {
return;
}
if (val < myNode->val[1]) {
*pos = 0;
} else {
for (*pos = myNode->count;
(val < myNode->val[*pos] && *pos > 1); (*pos)--)
;
if (val == myNode->val[*pos]) {
printf("%d is found", val);
return;
}
}
search(val, pos, myNode->link[*pos]);
return;
}
// Traverse then nodes
void traversal(struct BTreeNode *myNode) {
int i;
if (myNode) {
for (i = 0; i < myNode->count; i++) {
traversal(myNode->link[i]);
printf("%d ", myNode->val[i + 1]);
}
traversal(myNode->link[i]);
}
}

int main() {
int val, ch;
insert(8);
insert(9);
insert(10);
insert(11);
insert(15);
insert(16);
insert(17);
insert(18);
insert(20);
insert(23);
traversal(root);
printf("\n");
search(11, &ch, root);
}

b.

Exercise – 3
Program for max and min heap
#include <stdio.h>
#include <stdlib.h>
// Structure for Heap
typedef struct {
int *arr;
int size;
int capacity;
int isMaxHeap; // 1 for Max Heap, 0 for Min Heap
} Heap;

// Function to initialize a heap


Heap* createHeap(int capacity, int isMaxHeap) {
Heap *heap = (Heap*)malloc(sizeof(Heap));
heap->arr = (int*)malloc(capacity * sizeof(int));
heap->size = 0;
heap->capacity = capacity;
heap->isMaxHeap = isMaxHeap;
return heap;
}
// Swap function
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// Heapify Up (For Insert)
void heapifyUp(Heap *heap, int index) {
int parent = (index - 1) / 2;
if (index > 0) {
int condition = heap->isMaxHeap ? (heap->arr[index] > heap->arr[parent])
: (heap->arr[index] < heap->arr[parent]);
if (condition) {
swap(&heap->arr[index], &heap->arr[parent]);
heapifyUp(heap, parent);
}
}
}

// Insert into heap


void insert(Heap *heap, int value) {
if (heap->size == heap->capacity) {
printf("Heap is full!\n");
return;
}
heap->arr[heap->size] = value;
heapifyUp(heap, heap->size);
heap->size++;
}
// Heapify Down (For Delete)
void heapifyDown(Heap *heap, int index) {
int left = 2 * index + 1;
int right = 2 * index + 2;
int extreme = index;
if (left < heap->size) {
int condition = heap->isMaxHeap ? (heap->arr[left] > heap->arr[extreme])
: (heap->arr[left] < heap->arr[extreme]);
if (condition) extreme = left;
}
if (right < heap->size) {
int condition = heap->isMaxHeap ? (heap->arr[right] > heap->arr[extreme])
: (heap->arr[right] < heap->arr[extreme]);
if (condition) extreme = right;
}
if (extreme != index) {
swap(&heap->arr[index], &heap->arr[extreme]);
heapifyDown(heap, extreme);
}
}
// Delete root from heap
void deleteRoot(Heap *heap) {
if (heap->size == 0) {
printf("Heap is empty!\n");
return;
}
heap->arr[0] = heap->arr[heap->size - 1];
heap->size--;
heapifyDown(heap, 0);
}
// Display heap
void displayHeap(Heap *heap) {
if (heap->size == 0) {
printf("Heap is empty!\n");
return;
}
for (int i = 0; i < heap->size; i++) {
printf("%d ", heap->arr[i]);
}
printf("\n");
}

// Free memory
void freeHeap(Heap *heap) {
free(heap->arr);
free(heap);
}

// Main function
int main() {
int capacity, choice, value;
printf("Enter the capacity of the heap: ");
scanf("%d", &capacity);
printf("Choose Heap Type (1 for Max Heap, 0 for Min Heap): ");
int type;
scanf("%d", &type);
Heap *heap = createHeap(capacity, type);
while (1) {
printf("\n1. Insert\n2. Delete Root\n3. Display\n4. Exit\nEnter choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter value to insert: ");
scanf("%d", &value);
insert(heap, value);
break;
case 2:
deleteRoot(heap);
break;
case 3:
displayHeap(heap);
break;
case 4:
freeHeap(heap);
exit(0);
default:
printf("Invalid choice!\n");
}
}
return 0;
}
Exercise -4
a. Implement Graph and its operations
#include <stdio.h>
#include <stdlib.h>
// Define a structure for the adjacency list node
typedef struct Node {
int vertex;
struct Node* next;
} Node;
// Define a structure for the graph
typedef struct Graph {
int numVertices;
Node** adjLists;
int* visited;
} Graph;
// Function to create a new node
Node* createNode(int vertex) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->vertex = vertex;
newNode->next = NULL;
return newNode;
}
// Function to create a graph
Graph* createGraph(int vertices) {
Graph* graph = (Graph*)malloc(sizeof(Graph));
graph->numVertices = vertices;
graph->adjLists = (Node**)malloc(vertices * sizeof(Node*));
graph->visited = (int*)malloc(vertices * sizeof(int));
for (int i = 0; i < vertices; i++) {
graph->adjLists[i] = NULL;
graph->visited[i] = 0;
}
return graph;
}
// Function to add an edge to the graph
void addEdge(Graph* graph, int src, int dest) {
// Add edge from src to dest
Node* newNode = createNode(dest);
newNode->next = graph->adjLists[src];
graph->adjLists[src] = newNode;

// Add edge from dest to src (for an undirected graph)


newNode = createNode(src);
newNode->next = graph->adjLists[dest];
graph->adjLists[dest] = newNode;
}
// Function to display the graph
void displayGraph(Graph* graph) {
for (int i = 0; i < graph->numVertices; i++) {
Node* temp = graph->adjLists[i];
printf("Vertex %d:\n", i);
while (temp) {
printf(" -> %d", temp->vertex);
temp = temp->next;
}
printf("\n");
}
}
// Depth-First Search (DFS)
void DFS(Graph* graph, int vertex) {
graph->visited[vertex] = 1;
printf("%d ", vertex);
Node* temp = graph->adjLists[vertex];
while (temp) {
int connectedVertex = temp->vertex;
if (!graph->visited[connectedVertex]) {
DFS(graph, connectedVertex);
}
temp = temp->next;
}
}
// Breadth-First Search (BFS)
void BFS(Graph* graph, int startVertex) {
int* queue = (int*)malloc(graph->numVertices * sizeof(int));
int front = 0, rear = 0;
graph->visited[startVertex] = 1;
queue[rear++] = startVertex;
while (front != rear) {
int currentVertex = queue[front++];
printf("%d ", currentVertex);
Node* temp = graph->adjLists[currentVertex];
while (temp) {
int connectedVertex = temp->vertex;
if (!graph->visited[connectedVertex]) {
graph->visited[connectedVertex] = 1;
queue[rear++] = connectedVertex;
}
temp = temp->next;
}
}
free(queue);
}
// Function to reset visited array for traversal reuse
void resetVisited(Graph* graph) {
for (int i = 0; i < graph->numVertices; i++) {
graph->visited[i] = 0;
}
}
// Main function
int main() {
int vertices, edges, src, dest, choice, startVertex;
printf("Enter the number of vertices: ");
scanf("%d", &vertices);
Graph* graph = createGraph(vertices);
printf("Enter the number of edges: ");
scanf("%d", &edges);
printf("Enter the edges (source and destination):\n");
for (int i = 0; i < edges; i++) {
printf("Edge %d: ", i + 1);
scanf("%d %d", &src, &dest);
addEdge(graph, src, dest);
}
while (1) {
printf("\nMenu:\n");
printf("1. Display Graph\n");
printf("2. Depth-First Search (DFS)\n");
printf("3. Breadth-First Search (BFS)\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("\nGraph adjacency list:\n");
displayGraph(graph);
break;
case 2:
printf("\nEnter starting vertex for DFS: ");
scanf("%d", &startVertex);
resetVisited(graph);
printf("DFS Traversal:\n");
DFS(graph, startVertex);
printf("\n");
break;
case 3:
printf("\nEnter starting vertex for BFS: ");
scanf("%d", &startVertex);
resetVisited(graph);
printf("BFS Traversal:\n");
BFS(graph, startVertex);
printf("\n");
break;
case 4:
printf("Exiting program.\n");
free(graph->adjLists);
free(graph->visited);
free(graph);
return 0;
default:
printf("Invalid choice! Please try again.\n");
}
}
return 0;
}

Output:
Enter the number of vertices: 5
Enter the number of edges: 6
Enter the edges (source and destination):
Edge 1: 0 1
Edge 2: 0 4
Edge 3: 1 2
Edge 4: 1 3
Edge 5: 1 4
Edge 6: 3 4

Menu:
1. Display Graph
2. Depth-First Search (DFS)
3. Breadth-First Search (BFS)
4. Exit
Enter your choice: 1

Graph adjacency list:


Vertex 0:
-> 4 -> 1
Vertex 1:
-> 4 -> 3 -> 2 -> 0
Vertex 2:
-> 1
Vertex 3:
-> 4 -> 1
Vertex 4:
-> 3 -> 1 -> 0

Menu:
1. Display Graph
2. Depth-First Search (DFS)
3. Breadth-First Search (BFS)
4. Exit
Enter your choice: 2

Enter starting vertex for DFS: 0


DFS Traversal:
04312

Menu:
1. Display Graph
2. Depth-First Search (DFS)
3. Breadth-First Search (BFS)
4. Exit
Enter your choice: 3

Enter starting vertex for BFS: 0


BFS Traversal:
04132

Menu:
1. Display Graph
2. Depth-First Search (DFS)
3. Breadth-First Search (BFS)
4. Exit
Enter your choice: 4
Exiting program.

Exercise -5
Develop and implement an algorithm using divide and conquer strategy for a given set of problem
#include<stdio.h>
#include<stdio.h>
int max, min;
int a[100];
void maxmin(int i, int j)
{
int max1, min1, mid;
if(i==j)
{
max = min = a[i];
}
else
{
if(i == j-1)
{
if(a[i] <a[j])
{
max = a[j];
min = a[i];
}
else
{
max = a[i];
min = a[j];
}
}
else
{
mid = (i+j)/2;
maxmin(i, mid);
max1 = max; min1 = min;
maxmin(mid+1, j);
if(max <max1)
max = max1;
if(min > min1)
min = min1;
}
}
}
int main ()
{
int i, num;
printf ("\nEnter the total number of numbers : ");
scanf ("%d",&num);
printf ("Enter the numbers : \n");
for (i=1;i<=num;i++)
scanf ("%d",&a[i]);
max = a[0];
min = a[0];
maxmin(1, num);
printf ("Minimum element in an array : %d\n", min);
printf ("Maximum element in an array : %d\n", max);
return 0;
}
Output:
Enter the total number of numbers : 11
Enter the numbers :
5
1
9
45
19
15
17
100
0
56
13
Minimum element in an array : 0
Maximum element in an array : 100

Exercise:6
Make use of greedy method to implement a solution for a given problem
#include <stdio.h>
#define MAX 100
typedef struct Job {
char id[5];
int deadline;
int profit;
} Job;
void jobSequencingWithDeadline(Job jobs[], int n);
int minValue(int x, int y) {
if(x < y) return x;
return y;
}

int main(void) {
//variables
int i, j;
//jobs with deadline and profit
Job jobs[5] = {
{"j1", 2, 60},
{"j2", 1, 100},
{"j3", 3, 20},
{"j4", 2, 40},
{"j5", 1, 20},
};
//temp
Job temp;
//number of jobs
int n = 5;
//sort the jobs profit wise in descending order
for(i = 1; i < n; i++) {
for(j = 0; j < n - i; j++) {
if(jobs[j+1].profit > jobs[j].profit) {
temp = jobs[j+1];
jobs[j+1] = jobs[j];
jobs[j] = temp;
}
}
}
printf("%10s %10s %10s\n", "Job", "Deadline", "Profit");
for(i = 0; i < n; i++) {
printf("%10s %10i %10i\n", jobs[i].id, jobs[i].deadline, jobs[i].profit);
}
jobSequencingWithDeadline(jobs, n);
return 0;
}
void jobSequencingWithDeadline(Job jobs[], int n) {
//variables
int i, j, k, maxprofit;
//free time slots
int timeslot[MAX];
//filled time slots
int filledTimeSlot = 0;
//find max deadline value
int dmax = 0;
for(i = 0; i < n; i++) {
if(jobs[i].deadline > dmax) {
dmax = jobs[i].deadline;
}
}
//free time slots initially set to -1 [-1 denotes EMPTY]
for(i = 1; i <= dmax; i++) {
timeslot[i] = -1;
}
printf("dmax: %d\n", dmax);
for(i = 1; i <= n; i++) {
k = minValue(dmax, jobs[i - 1].deadline);
while(k >= 1) {
if(timeslot[k] == -1) {
timeslot[k] = i-1;
filledTimeSlot++;
break;
}
k--;
}
//if all time slots are filled then stop
if(filledTimeSlot == dmax) {
break;
}
}
//required jobs
printf("\nRequired Jobs: ");
for(i = 1; i <= dmax; i++) {
printf("%s", jobs[timeslot[i]].id);
if(i < dmax) {
printf(" --> ");
}
}
//required profit
maxprofit = 0;
for(i = 1; i <= dmax; i++) {
maxprofit += jobs[timeslot[i]].profit;
}
printf("\nMax Profit: %d\n", maxprofit);
}
Output:
Job Deadline Profit
j2 1 100
j1 2 60
j4 2 40
j3 3 20
j5 1 20
dmax: 3

Required Jobs: j2 --> j1 --> j3


Max Profit: 180

b.)
#include<stdio.h>
int main()
{
float weight[50],profit[50],ratio[50],Totalvalue,temp,capacity,amount;
int n,i,j;
printf("Enter the number of items :");
scanf("%d",&n);
for (i = 0; i < n; i++)
{
printf("Enter Weight and Profit for item[%d] :\n",i);
scanf("%f %f", &weight[i], &profit[i]);
}
printf("Enter the capacity of knapsack :\n");
scanf("%f",&capacity);

for(i=0;i<n;i++)
ratio[i]=profit[i]/weight[i];
for (i = 0; i < n; i++)
for (j = i + 1; j < n; 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;
}

printf("Knapsack problems using Greedy Algorithm:\n");


for (i = 0; i < n; i++)
{
if (weight[i] > capacity)
break;
else
{
Totalvalue = Totalvalue + profit[i];
capacity = capacity - weight[i];
}
}
if (i < n)
Totalvalue = Totalvalue + (ratio[i]*capacity);
printf("\nThe maximum value is :%f\n",Totalvalue);
return 0;
}
output:-

Enter the number of items :4


Enter Weight and Profit for item[0] :
2
12
Enter Weight and Profit for item[1] :
1
10
Enter Weight and Profit for item[2] :
3
20
Enter Weight and Profit for item[3] :
2
15
Enter the capacity of knapsack :
5
Knapsack problems using Greedy Algorithm:

The maximum value is :38.333332

7 dynamic programming using o/1 knapsack problem


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

// Function to compute maximum value in Knapsack using DP


int knapsack(int W, int weight[], int value[], int n) {
// Dynamic allocation of 2D DP array
int **dp = (int **)malloc((n + 1) * sizeof(int *));
for (int i = 0; i <= n; i++)
dp[i] = (int *)malloc((W + 1) * sizeof(int));

// Build the DP table in bottom-up manner


for (int i = 0; i <= n; i++) {
for (int w = 0; w <= W; w++) {
if (i == 0 || w == 0)
dp[i][w] = 0;
else if (weight[i - 1] <= w)
dp[i][w] = (value[i - 1] + dp[i - 1][w - weight[i - 1]] > dp[i - 1][w]) ?
(value[i - 1] + dp[i - 1][w - weight[i - 1]]) : dp[i - 1][w];
else
dp[i][w] = dp[i - 1][w];
}
}

int result = dp[n][W]; // Maximum value in Knapsack

// Free allocated memory


for (int i = 0; i <= n; i++)
free(dp[i]);
free(dp);
return result;
}

int main() {
int n, W;

// Taking user input


printf("Enter number of items: ");
scanf("%d", &n);

int *value = (int *)malloc(n * sizeof(int));


int *weight = (int *)malloc(n * sizeof(int));

printf("Enter values of items: ");


for (int i = 0; i < n; i++)
scanf("%d", &value[i]);

printf("Enter weights of items: ");


for (int i = 0; i < n; i++)
scanf("%d", &weight[i]);

printf("Enter Knapsack capacity: ");


scanf("%d", &W);

// Compute the maximum value that can be obtained


int maxValue = knapsack(W, weight, value, n);
printf("Maximum value in Knapsack = %d\n", maxValue);
// Free allocated memory
free(value);
free(weight);

return 0;
}

Output:
Enter number of items: 3
Enter values of items: 1
2
5
Enter weights of items: 2
3
4
Enter Knapsack capacity: 6
Maximum value in Knapsack = 6

8. backtracking n queen problem


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

// Function to print the solution


void printSolution(int* board, int N) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (board[i] == j)
printf(" Q ");
else
printf(" _ ");
}
printf("\n");
}
printf("\n");
}

// Check if a queen can be placed on board[row][col]


int isSafe(int* board, int row, int col, int N) {
for (int i = 0; i < row; i++) {
if (board[i] == col || abs(board[i] - col) == abs(i - row))
return 0;
}
return 1;
}

// Recursive function to solve the N-Queens problem


int solveNQueensUtil(int* board, int row, int N) {
if (row >= N) {
printSolution(board, N);
return 1;
}
int res = 0;
for (int col = 0; col < N; col++) {
if (isSafe(board, row, col, N)) {
board[row] = col;
res |= solveNQueensUtil(board, row + 1, N);
board[row] = -1; // Backtrack
}
}
return res;
}

// Solve N-Queens using dynamic values


void solveNQueens(int N) {
int* board = (int*)malloc(N * sizeof(int));
for (int i = 0; i < N; i++)
board[i] = -1;

if (!solveNQueensUtil(board, 0, N)) {
printf("No solution exists for N = %d\n", N);
}
free(board);
}
int main() {
int N;
printf("Enter the number of queens (N): ");
scanf("%d", &N);
if (N <= 0) {
printf("Invalid input. N should be greater than 0.\n");
return 1;
}
solveNQueens(N);
return 0;
}
Output:
Enter the number of queens (N): 4
_ Q _ _
_ _ _ Q
Q _ _ _
_ _ Q _

_ _ Q _
Q _ _ _
_ _ _ Q
_ Q _ _

Output: 2
Enter the number of queens (N): 3
No solution exists for N = 3

9. branch and bound


#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// Structure to represent an item with weight, value, and ratio
typedef struct {
int weight;
int value;
double ratio;
} Item;
// Structure to represent a node in the decision tree
typedef struct {
int level;
int profit;
int weight;
double bound;
} Node;
// Comparator function to sort items based on value/weight ratio
int compare(const void *a, const void *b) {
Item *itemA = (Item *)a;
Item *itemB = (Item *)b;
return (itemB->ratio > itemA->ratio) - (itemB->ratio < itemA->ratio);
}
// Function to calculate the upper bound of profit for a node
double bound(Node u, int n, int W, Item items[]) {
if (u.weight >= W)
return 0;
double profitBound = u.profit;
int j = u.level + 1;
int totalWeight = u.weight;
while (j < n && totalWeight + items[j].weight <= W) {
totalWeight += items[j].weight;
profitBound += items[j].value;
j++;
}
if (j < n)
profitBound += (W - totalWeight) * items[j].ratio;
return profitBound;
}
// Branch and Bound Algorithm to solve Knapsack Problem
int knapsack(int W, Item items[], int n) {
qsort(items, n, sizeof(Item), compare);
Node u, v;
u.level = -1;
u.profit = u.weight = 0;
double maxProfit = 0;
Node queue[1000];
int front = 0, rear = 0;
queue[rear++] = u;
while (front < rear) {
u = queue[front++];
if (u.level == n-1)
continue;
v.level = u.level + 1;
// Include current item
v.weight = u.weight + items[v.level].weight;
v.profit = u.profit + items[v.level].value;

if (v.weight <= W && v.profit > maxProfit)


maxProfit = v.profit;
v.bound = bound(v, n, W, items);
if (v.bound > maxProfit)
queue[rear++] = v;
// Exclude current item
v.weight = u.weight;
v.profit = u.profit;
v.bound = bound(v, n, W, items);
if (v.bound > maxProfit)
queue[rear++] = v;
}
return maxProfit;
}
int main() {
int n, W;
printf("Enter number of items: ");
scanf("%d", &n);
printf("Enter maximum weight of the knapsack: ");
scanf("%d", &W);
Item *items = (Item *)malloc(n * sizeof(Item));
for (int i = 0; i < n; i++) {
printf("Enter value and weight of item %d: ", i + 1);
scanf("%d %d", &items[i].value, &items[i].weight);
items[i].ratio = (double)items[i].value / items[i].weight;
}
int maxProfit = knapsack(W, items, n);
printf("Maximum Profit: %d\n", maxProfit);
free(items);
return 0;
}
Output:
Enter number of items: 5
Enter maximum weight of the knapsack: 20
Enter value and weight of item 1: 4
3
Enter value and weight of item 2: 5
7
Enter value and weight of item 3: 5
6
Enter value and weight of item 4: 8
9
Enter value and weight of item 5: 5
5
Maximum Profit: 20

10. Case Study-1:


Apply the most appropriate design technique to develop and implement an efficient solution for a
given problem.
To solve Case Study 1 where you need to apply the most appropriate design technique to develop
and implement an efficient solution, let's follow these steps using a sample problem.
Step 1: Analyze the Problem
 Input:
o Number of items n
o Array of item weights w[]
o Array of item values v[]
o Maximum weight capacity W
 Output:
o Maximum possible value without exceeding the weight capacity.
Step 2: Choose the Most Appropriate Design Technique
The Knapsack Problem is a classic optimization problem.
Since it involves finding the best solution among multiple possible selections, we can apply one of the
following techniques:
1. Brute Force: Try all possible subsets — inefficient for large inputs (O(2^n)).
2. Greedy Algorithm: Not suitable as it may not provide the optimal solution for all cases.
3. Dynamic Programming (DP): Efficient for solving optimization problems using overlapping
subproblems (O(n * W)).
4. Branch and Bound: Ideal for solving large-scale optimization problems with pruning, reducing
unnecessary computations.
➡ Most Appropriate Technique:
Dynamic Programming (DP) using a bottom-up approach is generally preferred for the 0/1 Knapsack
Problem.
Step 3: Develop the Solution Using DP
Approach:
 Create a 2D table dp[n+1][W+1] where:
o dp[i][j] stores the maximum value using the first i items with a weight limit of j.
 Recurrence Relation:

dp[i][j]=max⁡(dp[i−1][j],v[i−1]+dp[i−1][j−w[i−1]])dp[i][j] = \max(dp[i-1][j], v[i-1] + dp[i-1][j-w[i-1]])dp[i]


[j]=max(dp[i−1][j],v[i−1]+dp[i−1][j−w[i−1]])
Where:
 dp[i-1][j] = Value without including the item
 v[i-1] + dp[i-1][j-w[i-1]] = Value including the item
Base Case:
 If no items or no capacity → dp[i][0] = dp[0][j] = 0

Step 4: Implement the Solution

 Here’s a sample implementation in C

Source code:
#include <stdio.h>
// Function to find the maximum value using Dynamic Programming
int knapsack(int W, int wt[], int val[], int n) {
int dp[n + 1][W + 1];
// Build the DP table
for (int i = 0; i <= n; i++) {
for (int w = 0; w <= W; w++) {
if (i == 0 || w == 0)
dp[i][w] = 0;
else if (wt[i - 1] <= w)
dp[i][w] = (val[i - 1] + dp[i - 1][w - wt[i - 1]] > dp[i - 1][w]) ?
val[i - 1] + dp[i - 1][w - wt[i - 1]] : dp[i - 1][w];
else
dp[i][w] = dp[i - 1][w];
}
}
return dp[n][W];
}
int main() {
int n, W;
printf("Enter number of items: ");
scanf("%d", &n);
int val[n], wt[n];
printf("Enter weight and value of each item (weight value):\n");
for (int i = 0; i < n; i++) {
scanf("%d %d", &wt[i], &val[i]);
}
printf("Enter maximum weight capacity: ");
scanf("%d", &W);
int maxProfit = knapsack(W, wt, val, n);
printf("Maximum value in Knapsack: %d\n", maxProfit);
return 0;
}
Output:
Enter number of items: 5
Enter weight and value of each item (weight value):
4
5
3
4
6
7
Enter maximum weight capacity: 15
Maximum value in Knapsack: 16
This C program uses a Dynamic Programming approach to solve the 0/1 Knapsack Problem. It
efficiently calculates the maximum possible value within the weight limit.

11. Case Study-2:


Develop and implement an optimal solution for a given problem by applying a suitable design
technique.

For Case Study 2, we can follow a structured approach to develop and implement an optimal
solution using a suitable design technique. Here's how you can approach it:
Step 1: Problem Understanding
 Carefully read the given problem statement.
 Identify the key elements: inputs, outputs, constraints, and goals.
 Determine whether it's an optimization problem (e.g., finding the shortest path, maximizing
profit) or a decision problem (e.g., checking feasibility).
Step 2: Problem Formulation
 Define the problem with clear variables, constraints, and objectives.
 Example:
o Input: Set of data values, constraints, and objective function.
o Output: Optimal or feasible solution based on the constraints.
Step 3: Choose a Suitable Design Technique
Select the most appropriate design technique based on the problem nature:
1. Dynamic Programming (DP) - Suitable for problems with overlapping subproblems and
optimal substructure.
2. Greedy Algorithm - Ideal when making a local choice at each step leads to the optimal
solution.
3. Divide and Conquer - Best for breaking down large problems into smaller subproblems (e.g.,
Merge Sort, Quick Sort).
4. Backtracking - Effective for constraint satisfaction problems (e.g., N-Queens, Sudoku).
5. Branch and Bound - Used for optimization problems with large solution spaces (e.g.,
Knapsack, TSP).
6. Graph Algorithms - Applicable for network-related problems (e.g., shortest path, MST).
Example Problem for Case Study 2
Problem:
Given a graph represented as a weighted adjacency matrix, find the shortest path from a source node
to all other nodes using an optimal design technique.
 Optimal Technique: Use Dijkstra’s Algorithm for shortest path finding in a weighted graph.
 Reason: Efficient for graphs with non-negative weights.
Step 4: Implement the Solution
Here is a C implementation of Dijkstra’s Algorithm using a priority queue for optimization.
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>
#define MAX 100
int minDistance(int dist[], bool sptSet[], int V) {
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++) {
if (!sptSet[v] && dist[v] <= min) {
min = dist[v];
min_index = v;
}
}
return min_index;
}
void printSolution(int dist[], int V) {
printf("Vertex \t Distance from Source\n");
for (int i = 0; i < V; i++) {
printf("%d \t %d\n", i, dist[i]);
}
}
void dijkstra(int graph[MAX][MAX], int src, int V) {
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, V);
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 V;
printf("Enter number of vertices: ");
scanf("%d", &V);
int graph[MAX][MAX];
printf("Enter the adjacency matrix (use 0 for no edge):\n");
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
scanf("%d", &graph[i][j]);
}
}
int src;
printf("Enter source vertex: ");
scanf("%d", &src);

dijkstra(graph, src, V);


return 0;
}
Output:
Enter number of vertices: 4
Enter the adjacency matrix (use 0 for no edge):
1 5 6 3
4 6 1 5
7 2 9 3
1 5 4 2
Enter source vertex: 1
Vertex Distance from Source
0 4
1 0
2 1
3 4
This program uses Dijkstra's Algorithm to calculate the shortest path from a given source node to all
other nodes in a weighted graph.
 Time Complexity: O(V2)O(V^2)O(V2) using a simple array.
 Space Complexity: O(V)O(V)O(V).

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