Download as pdf or txt
Download as pdf or txt
You are on page 1of 53

Index

Practical Practical Name


No.
1 Program for quicksort using recursion
2 Program for quicksort and time calculations
3 Program for external sorting: Merge sort
Program for internal sorting: Insertion sort
4 Program for Searching Algorithm
Sequential: Linear Search
Divide and Conquer: Binary Search
5 Program for AVL Tree
6 Program for 8 queens problem
7 Program to find strongly connected components in a
digraph
8 Program for Huffman’s algorithm
9 Program for Floyd-Warshall algorithm
10-a Program to solve 0/1 knapsack problem using
Greedy algorithm
10-b Program to solve 0/1 knapsack problem using
Dynamic Programming Algorithm
10-c Program to solve 0/1 knapsack problem using
Backtracking Algorithm
10-d Program to solve 0/1 knapsack problem using
Branch and Bound algorithm
11 Program to solve optimal binary tree
12-a Program to solve Travelling Salesman Problem using
Dynamic Programming Algorithm
12-b Program to solve Travelling Salesman Problem using
Backtracking Algorithm
12-c Program to solve Travelling Salesman Problem using
Branch and Bound Algorithm
Laboratory Practicals
1. Programming that uses recurrence relations to analyze recursive algorithms.
Quicksort using recursion algorithm
#include <stdio.h>

int partition(int a[], int low, int high)


{
int pivot = a[high];
int i = (low - 1);

for (int j = low; j <= high; j++)


{
if (a[j]<pivot)
{
i++;

int temp = a[i];


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

int temp = a[i+1];


a[i+1] = a[high];
a[high] = temp;

return (i + 1);
}

void quickSort(int a[], int low, int high)


{
if(low<high)
{
int part = partition(a, low, high);

quickSort(a, low, part - 1);


quickSort(a, part + 1, high);
}
}

int main()
{
int a[100], n, i;
printf("Enter the number of elements of array upto 100:");
scanf("%d", &n);

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


{
printf("Enter a[%d]th element: ", i);
scanf("%d", &a[i]);
}

quickSort(a, 0, n-1);

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

return 0;
}
Output
2. Computing best, average, and worst-case time complexity of
various sorting techniques.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void Exch(int *p, int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
void QuickSort(int a[], int low, int high)
{
int i, j, key, k;
if (low >= high)
return;
key = low;
i = low + 1;
j = high;
while (i <= j)
{
while (a[i] <= a[key])
i = i + 1;
while (a[j] > a[key])
j = j - 1;
if (i < j)
Exch(&a[i], &a[j]);
}
Exch(&a[j], &a[key]);
QuickSort(a, low, j - 1);
QuickSort(a, j + 1, high);
}
void main()
{
int n, a[1000], k;
clock_t st, et;
double ts;
printf("\n Enter How many Numbers: ");
scanf("%d", &n);
printf("\nThe Random Numbers are:\n");
for (k = 1; k <= n; k++)
{
a[k] = rand();
printf("%d\t", a[k]);
}
st = clock();
QuickSort(a, 1, n);
et = clock();
ts = (double)(et - st) / CLOCKS_PER_SEC;
printf("\nSorted Numbers are: \n ");
for (k = 1; k <= n; k++)
printf("%d\t", a[k]);
printf("\nThe time taken is %e", ts);
}
Output:
3. Performance analysis of different internal and external sorting
algorithms with different type of data set.
External Sorting Algorithm: Merge Sort
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void Merge(int a[], int low, int mid, int high)
{
int i, j, k, b[20];
i = low;
j = mid + 1;
k = low;
while (i <= mid && j <= high)
{
if (a[i] <= a[j])
b[k++] = a[i++];
else
b[k++] = a[j++];
}
while (i <= mid)
b[k++] = a[i++];
while (j <= high)
b[k++] = a[j++];
for (k = low; k <= high; k++)
a[k] = b[k];
}
void MergeSort(int a[], int low, int high)
{
int mid;
if (low >= high)
return;
mid = (low + high) / 2;
MergeSort(a, low, mid);
MergeSort(a, mid + 1, high);
Merge(a, low, mid, high);
}
void main()
{
int n, a[2000], k;
clock_t st, et;
double ts;
printf("\n Enter How many Numbers:");
scanf("%d", &n);
printf("\nThe Random Numbers are:\n");
for (k = 1; k <= n; k++)
{
a[k] = rand();
printf("%d\t", a[k]);
}
st = clock();
MergeSort(a, 1, n);
et = clock();
ts = (double)(et - st) / CLOCKS_PER_SEC;
printf("\n Sorted Numbers are : \n ");
for (k = 1; k <= n; k++)
printf("%d\t", a[k]);
printf("\nThe time taken is %e", ts);
}

Output
Internal Sorting Algorithm: Insertion Sort
#include <math.h>
#include <time.h>
#include <stdio.h>

void insertionSort(int arr[], int n)


{
int i, key, j;
for (i = 1; i < n; i++) {
key = arr[i];
j = i - 1;

while (j >= 0 && arr[j] > key) {


arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}

void printArray(int arr[], int n)


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

int main()
{
int arr[] = { 12, 11, 13, 5, 6 };
int n = sizeof(arr) / sizeof(arr[0]);
clock_t st, et;
double ts;

printf("The unsorted array is: \n");


printArray(arr, n);
st = clock();
insertionSort(arr, n);
et = clock();
ts = (double)(et - st) / CLOCKS_PER_SEC;
printf("The sorted array is: \n");
printArray(arr, n);
printf("\nThe time taken is %e", ts);

return 0;
}
Output
4. Use of divide and conquer technique to solve some problem
that uses two different algorithms for solving
small problem
Searching Algorithm (Sequential technique): Linear Search
#include <stdio.h>

int search(int array[], int n, int x) {

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


if (array[i] == x)
return i;
return -1;
}

int main() {
int array[] = {2, 4, 0, 1, 9};
int x = 1;
int n = sizeof(array) / sizeof(array[0]);

int result = search(array, n, x);


printf("The array is: \n");
for (int i = 0; i < 5; i++)
{
printf("%d, ", array[i]);
}

printf("\nElement to be found: %d", x);


(result == -1) ? printf("\nElement not found") : printf("\nElement
found at index: %d", result);
}
Output
Searching Algorithm (Divide and Conquer technique): Binary Search
#include <stdio.h>

int binarySearch(int array[], int x, int low, int high) {


// Repeat until the pointers low and high meet each other
while (low <= high) {
int mid = low + (high - low) / 2;

if (array[mid] == x)
return mid;

if (array[mid] < x)
low = mid + 1;

else
high = mid - 1;
}

return -1;
}

int main(void) {
int array[] = {3, 4, 5, 6, 7, 8, 9};
int n = sizeof(array) / sizeof(array[0]);
int x = 4;
int result = binarySearch(array, x, 0, n - 1);
printf("The array is: \n");
for (int i = 0; i < 5; i++)
{
printf("%d, ", array[i]);
}
printf("\nElement to be found: %d", x);
if (result == -1)
printf("\nNot found");
else
printf("\nElement is found at index %d", result);
return 0;
}
Output
5. Implementation of different basic computing algorithms like
AVL tree
#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);

printf("\nBefore deletion: ");


printPreOrder(root);

root = deleteNode(root, 3);

printf("\nAfter deletion: ");


printPreOrder(root);

return 0;
}
Output
6. Consider the problem of eight queens on an (8x8) chessboard.
Two queens are said to attack each other if they
are on the same row, column, or diagonal. Write a program that
implements backtracking algorithm to solve
the problem i.e. place eight non-attacking queens on the board.
#define N 8
#include <stdbool.h>
#include <stdio.h>

void printSolution(int board[N][N])


{
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
printf(" %d ", board[i][j]);
printf("\n");
}
}

bool isSafe(int board[N][N], int row, int col)


{
int i, j;

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


if (board[row][i])
return false;

for (i = row, j = col; i >= 0 && j >= 0; i--, j--)


if (board[i][j])
return false;

for (i = row, j = col; j >= 0 && i < N; i++, j--)


if (board[i][j])
return false;

return true;
}

bool solveNQUtil(int board[N][N], int col)


{
if (col >= N)
return true;

for (int i = 0; i < N; i++) {


if (isSafe(board, i, col)) {
board[i][col] = 1;

if (solveNQUtil(board, col + 1))


return true;

board[i][col] = 0;
}
}

return false;
}

bool solveNQ()
{
int board[N][N] = { { 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 } };

if (solveNQUtil(board, 0) == false) {
printf("Solution does not exist");
return false;
}

printSolution(board);
return true;
}

int main()
{
solveNQ();
return 0;
}
Output
7. Write a program to find the strongly connected components
in a digraph
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_SIZE 5
struct Graph *graph;
struct Graph *gr;
int stack[MAX_SIZE], top;
struct adj_list_node
{
int dest;
int weight;
struct adj_list_node *next;
};
struct adj_list
{
struct adj_list_node *head;
};
struct Graph
{
int V;
int *visited;
struct adj_list *array;
};
struct adj_list_node *new_adj_list_node(int dest, int weight)
{
struct adj_list_node *newNode = (struct adj_list_node
*)malloc(sizeof(struct adj_list_node));
newNode->dest = dest;
newNode->weight = weight;
newNode->next = NULL;
return newNode;
}
struct Graph *create_graph(int V)
{
struct Graph *graph = (struct Graph *)malloc(sizeof(struct Graph));
graph->V = V;
graph->array = (struct adj_list *)malloc(V * sizeof(struct adj_list));
int i;
for (i = 0; i < V; ++i)
graph->array[i].head = NULL;
return graph;
}
void add_edge(struct Graph *graph, struct Graph *gr, int src, int
dest, int weight)
{
struct adj_list_node *newNode = new_adj_list_node(dest, weight);
newNode->next = graph->array[src].head;
graph->array[src].head = newNode;
get_transpose(gr, src, dest, weight);
}
void print_graph(struct Graph *graph1)
{
int v;
for (v = 0; v < graph1->V; ++v)
{
struct adj_list_node *temp = graph1->array[v].head;
while (temp)
{
printf("(%d -> %d(%d))\t", v, temp->dest, temp->weight);
temp = temp->next;
}
}
}
void set_fill_order(struct Graph *graph, int v, bool visited[], int
*stack)
{
visited[v] = true;
int i = 0;
struct adj_list_node *temp = graph->array[v].head;
while (temp)
{
if (!visited[temp->dest])
{
set_fill_order(graph, temp->dest, visited, stack);
}
temp = temp->next;
}
push(v);
}
void dfs_recursive(struct Graph *gr, int v, bool visited[])
{
visited[v] = true;
printf("%d ", v);
struct adj_list_node *temp = gr->array[v].head;
while (temp)
{
if (!visited[temp->dest])
{
dfs_recursive(gr, temp->dest, visited);
}
temp = temp->next;
}
}
void get_transpose(struct Graph *gr, int src, int dest, int weight)
{
struct adj_list_node *newNode = new_adj_list_node(src, weight);
newNode->next = gr->array[dest].head;
gr->array[dest].head = newNode;
}
void strongly_connected_components(struct Graph *graph, struct
Graph *gr, int V)
{
bool visited[V];
for (int i = 0; i < V; i++)
visited[i] = false;
for (int i = 0; i < V; i++)
{
if (visited[i] == false)
{
set_fill_order(graph, i, visited, stack);
}
}
int count = 1;
for (int i = 0; i < V; i++)
visited[i] = false;
while (top != -1)
{
int v = stack[top];
pop();
if (visited[v] == false)
{
printf("Strongly connected component %d: \n", count++);
dfs_recursive(gr, v, visited);
printf("\n");
}
}
}
void push(int x)
{
if (top >= MAX_SIZE - 1)
{
printf("\n\tSTACK is over flow");
}
else
{
top++;
stack[top] = x;
}
}
void pop()
{
if (top <= -1)
{
printf("\n\t Stack is under flow");
}
else
{
top--;
}
}
int main()
{
top = -1;
int v = 5;
struct Graph *graph = create_graph(v);
struct Graph *gr = create_graph(v);
add_edge(graph, gr, 1, 0, 2);
add_edge(graph, gr, 0, 2, 2);
add_edge(graph, gr, 2, 1, 2);
add_edge(graph, gr, 0, 3, 2);
add_edge(graph, gr, 3, 4, 2);
strongly_connected_components(graph, gr, v);
return 0;
}
Output
8. Write a program to implement file compression (and un-
compression) using Huffman’s algorithm.
#include <stdio.h>
#include <stdlib.h>

#define MAX_TREE_HT 50

struct MinHNode
{
char item;
unsigned freq;
struct MinHNode *left, *right;
};

struct MinHeap
{
unsigned size;
unsigned capacity;
struct MinHNode **array;
};

struct MinHNode *newNode(char item, unsigned freq)


{
struct MinHNode *temp = (struct MinHNode *)malloc(sizeof(struct
MinHNode));

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


temp->item = item;
temp->freq = freq;

return temp;
}

struct MinHeap *createMinH(unsigned capacity)


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

minHeap->size = 0;
minHeap->capacity = capacity;

minHeap->array = (struct MinHNode **)malloc(minHeap->capacity


* sizeof(struct MinHNode *));
return minHeap;
}

void swapMinHNode(struct MinHNode **a, struct MinHNode **b)


{
struct MinHNode *t = *a;
*a = *b;
*b = t;
}

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)
{
swapMinHNode(&minHeap->array[smallest], &minHeap-
>array[idx]);
minHeapify(minHeap, smallest);
}
}

int checkSizeOne(struct MinHeap *minHeap)


{
return (minHeap->size == 1);
}

struct MinHNode *extractMin(struct MinHeap *minHeap)


{
struct MinHNode *temp = minHeap->array[0];
minHeap->array[0] = minHeap->array[minHeap->size - 1];

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

return temp;
}

void insertMinHeap(struct MinHeap *minHeap, struct MinHNode


*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;
}

void buildMinHeap(struct MinHeap *minHeap)


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

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


minHeapify(minHeap, i);
}

int isLeaf(struct MinHNode *root)


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

struct MinHeap *createAndBuildMinHeap(char item[], int freq[], int


size)
{
struct MinHeap *minHeap = createMinH(size);

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


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

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

return minHeap;
}

struct MinHNode *buildHuffmanTree(char item[], int freq[], int size)


{
struct MinHNode *left, *right, *top;
struct MinHeap *minHeap = createAndBuildMinHeap(item, freq,
size);

while (!checkSizeOne(minHeap))
{
left = extractMin(minHeap);
right = extractMin(minHeap);

top = newNode('$', left->freq + right->freq);

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

insertMinHeap(minHeap, top);
}
return extractMin(minHeap);
}
void printHCodes(struct MinHNode *root, int arr[], int top)
{
if (root->left)
{
arr[top] = 0;
printHCodes(root->left, arr, top + 1);
}
if (root->right)
{
arr[top] = 1;
printHCodes(root->right, arr, top + 1);
}
if (isLeaf(root))
{
printf(" %c | ", root->item);
printArray(arr, top);
}
}

void HuffmanCodes(char item[], int freq[], int size)


{
struct MinHNode *root = buildHuffmanTree(item, freq, size);

int arr[MAX_TREE_HT], top = 0;

printHCodes(root, arr, top);


}

void printArray(int arr[], int n)


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

printf("\n");
}

int main()
{
char arr[] = {'A', 'B', 'C', 'D'};
int freq[] = {5, 1, 6, 3};

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

printf(" Char | Huffman code ");


printf("\n--------------------\n");

HuffmanCodes(arr, freq, size);


}
Output
9. Write a program to implement dynamic programming
algorithm to solve the all-pairs shortest path problem.
Floyd-Warshall Algorithm

#include <stdio.h>
#define nV 4

#define INF 999

void printMatrix(int matrix[][nV]);

void floydWarshall(int graph[][nV]) {


int matrix[nV][nV], i, j, k;

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


for (j = 0; j < nV; j++)
matrix[i][j] = graph[i][j];

for (k = 0; k < nV; k++) {


for (i = 0; i < nV; i++) {
for (j = 0; j < nV; j++) {
if (matrix[i][k] + matrix[k][j] < matrix[i][j])
matrix[i][j] = matrix[i][k] + matrix[k][j];
}
}
}
printMatrix(matrix);
}

void printMatrix(int matrix[][nV]) {


for (int i = 0; i < nV; i++) {
for (int j = 0; j < nV; j++) {
if (matrix[i][j] == INF)
printf("%4s", "INF");
else
printf("%4d", matrix[i][j]);
}
printf("\n");
}
}

int main() {
int graph[nV][nV] = {{0, 3, INF, 5},
{2, 0, INF, 4},
{INF, 1, 0, INF},
{INF, INF, 2, 0}};
floydWarshall(graph);
}
Output
10. Write a program to solve 0/1 knapsack problem using the
following:
a) Greedy algorithm
#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;
}
Output
b) Dynamic Programming
#include <stdio.h>
#include <conio.h>
int w[10], p[10], v[10][10], n, i, j, cap, x[10] = {0};
int max(int i, int j)
{
return ((i > j) ? i : j);
}
int knap(int i, int j)
{
int value;
if (v[i][j] < 0)
{
if (j < w[i])
value = knap(i - 1, j);
else
value = max(knap(i - 1, j), p[i] + knap(i - 1, j - w[i]));
v[i][j] = value;
}
return (v[i][j]);
}
void main()
{
int profit, count = 0;
//clrscr();
printf("\nEnter the number of elements\n");
scanf("%d", &n);
printf("Enter the profit and weights of the elements\n");
for (i = 1; i <= n; i++)
{
printf("For item no %d\n", i);
scanf("%d%d", &p[i], &w[i]);
}
printf("\nEnter the capacity \n");
scanf("%d", &cap);
for (i = 0; i <= n; i++)
for (j = 0; j <= cap; j++)
if ((i == 0) || (j == 0))
v[i][j] = 0;
else
v[i][j] = -1;
profit = knap(n, cap);
i = n;
j = cap;
while (j != 0 && i != 0)
{
if (v[i][j] != v[i - 1][j])
{
x[i] = 1;
j = j - w[i];
i--;
}
else
i--;
}
printf("Items included are\n");
printf("Sl.no\tweight\tprofit\n");
for (i = 1; i <= n; i++)
if (x[i])
printf("%d\t%d\t%d\n", ++count, w[i], p[i]);
printf("Total profit = %d\n", profit);
getch();
}
Output
c) Backtracking Algorithm
#include <stdio.h>
#define MAX 20
float final_profit;
int w[MAX];
int p[MAX];
int n, m;
int temp[MAX], x[MAX];
float final_wt;

float Bound_Calculation(int, int, int);


void BackTracking(int, int, int);

void main()
{
int i;
printf("\n Enter number of Objects you want:");
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
printf("\n Enter Weight and value for object%d:", i);
scanf("%3d %3d", &w[i], &p[i]);
}
printf("\n Enter Capacity of Knapsack:");
scanf("%d", &m);
printf("\n Weight\tProfit");

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


{
printf("\n %d \t %d", w[i], p[i]);
}

BackTracking(1, 0, 0);

printf("\n Following Objects are included:");


for (i = 1; i <= n; i++)
{
if (x[i] == 1)
printf("\n%d", i);
}
printf("\n Final Weight:%0.2f", final_wt);
printf("\n Final Profit:%0.2f", final_profit);
getch();
}
float Bound_Calculation(int cp, int cw, int k)
{
int ub, c, i;
ub = cp;
c = cw;
for (i = k + 1; i <= n; i++)
{
c = c + w[i];
if (c < m)
ub = ub + p[i];
else
return (ub + (1 - (c - m) / w[i]) * p[i]);
}
return ub;
}
void BackTracking(int k, int cp, int cw)
{
int new_k, new_cp, new_cw, j;
if (cw + w[k] <= m)
{
temp[k] = 1;
if (k < n)
{
new_k = k + 1;
new_cp = cp + p[k];
new_cw = cw + w[k];
BackTracking(new_k, new_cp, new_cw);
}
if ((new_cp > final_profit) && (k == n))
{
final_profit = new_cp;
final_wt = new_cw;
for (j = 1; j <= k; j++)
{
x[j] = temp[j];
}
}
}

if (Bound_Calculation(cp, cw, k) >= final_profit)


{
temp[k] = 0;
if (k < n)
BackTracking(k + 1, cp, cw);
if ((cp > final_profit) && (k == n))
{
final_profit = cp;
final_wt = cw;
for (j = 1; j <= n; j++)
x[j] = temp[j];
}
}
}
Output
d) Branch and Bound
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef enum
{
NO,
YES
} BOOL;

int N;
int vals[100];
int wts[100];

int cap = 0;
int mval = 0;

void getWeightAndValue(BOOL incl[N], int *weight, int *value)


{
int i, w = 0, v = 0;
for (i = 0; i < N; ++i)
{
if (incl[i])
{
w += wts[i];
v += vals[i];
}
}
*weight = w;
*value = v;
}

void printSubset(BOOL incl[N])


{
int i;
int val = 0;
printf("Included = { ");
for (i = 0; i < N; ++i)
{
if (incl[i])
{
printf("%d ", wts[i]);
val += vals[i];
}
}
printf("}; Total value = %d\n", val);
}

void findKnapsack(BOOL incl[N], int i)


{
int cwt, cval;
getWeightAndValue(incl, &cwt, &cval);
if (cwt <= cap)
{
if (cval > mval)
{
printSubset(incl);
mval = cval;
}
}
if (i == N || cwt >= cap)
{
return;
}
int x = wts[i];
BOOL use[N], nouse[N];
memcpy(use, incl, sizeof(use));
memcpy(nouse, incl, sizeof(nouse));
use[i] = YES;
nouse[i] = NO;
findKnapsack(use, i + 1);
findKnapsack(nouse, i + 1);
}

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


{
printf("Enter the number of elements: ");
scanf(" %d", &N);
BOOL incl[N];
int i;
for (i = 0; i < N; ++i)
{
printf("Enter weight and value for element %d: ", i + 1);
scanf(" %d %d", &wts[i], &vals[i]);
incl[i] = NO;
}
printf("Enter knapsack capacity: ");
scanf(" %d", &cap);
findKnapsack(incl, 0);
return 0;
}
Output
11. Write a program that uses dynamic programming algorithm to
solve the optimal binary search tree problem
#include <stdio.h>
#include <limits.h>

int sum(int freq[], int i, int j);

int optCost(int freq[], int i, int j)


{
if (j < i)
return 0;
if (j == i)
return freq[i];

int fsum = sum(freq, i, j);

int min = INT_MAX;

for (int r = i; r <= j; ++r)


{
int cost = optCost(freq, i, r-1) +
optCost(freq, r+1, j);
if (cost < min)
min = cost;
}

return min + fsum;


}

int optimalSearchTree(int keys[], int freq[], int n)


{
return optCost(freq, 0, n-1);
}

int sum(int freq[], int i, int j)


{
int s = 0;
for (int k = i; k <=j; k++)
s += freq[k];
return s;
}

int main()
{
int keys[] = {10, 12, 20};
int freq[] = {34, 8, 50};
int n = sizeof(keys)/sizeof(keys[0]);
printf("Cost of Optimal BST is %d ",
optimalSearchTree(keys, freq, n));
return 0;
}
Output
12. Write a program for solving traveling sales persons problem
using the following:
a) Dynamic programming algorithm
#include <iostream>

using namespace std;

const int n = 4;

const int MAX = 1000000;

int dist[n + 1][n + 1] = {


{0, 0, 0, 0, 0},
{0, 0, 10, 15, 20},
{0, 10, 0, 25, 25},
{0, 15, 25, 0, 30},
{0, 20, 25, 30, 0},
};

int memo[n + 1][1 << (n + 1)];

int fun(int i, int mask)


{
if (mask == ((1 << i) | 3))
return dist[1][i];

if (memo[i][mask] != 0)
return memo[i][mask];

int res = MAX;

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


if ((mask & (1 << j)) && j != i && j != 1)
res = std::min(res, fun(j, mask & (~(1 << i))) + dist[j][i]);
return memo[i][mask] = res;
}

int main()
{
int ans = MAX;
for (int i = 1; i <= n; i++)
ans = std::min(ans, fun(i, (1 << (n + 1)) - 1) + dist[i][1]);

printf("The cost of most efficient tour = %d", ans);

return 0;
}
Output
b) Backtracking algorithm
#include <bits/stdc++.h>
using namespace std;
#define V 4

void tsp(int graph[][V], vector<bool> &v, int currPos,


int n, int count, int cost, int &ans)
{
if (count == n && graph[currPos][0])
{
ans = min(ans, cost + graph[currPos][0]);
return;
}

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


{
if (!v[i] && graph[currPos][i])
{

v[i] = true;
tsp(graph, v, i, n, count + 1,
cost + graph[currPos][i], ans);

v[i] = false;
}
}
};

int main()
{
int n = 4;

int graph[][V] = {
{0, 10, 15, 20},
{10, 0, 35, 25},
{15, 35, 0, 30},
{20, 25, 30, 0}};

vector<bool> v(n);
for (int i = 0; i < n; i++)
v[i] = false;

v[0] = true;
int ans = INT_MAX;

tsp(graph, v, 0, n, 1, 0, ans);

cout << ans;

return 0;
}
Output
c) Branch and bound
#include <bits/stdc++.h>
using namespace std;
const int N = 4;

int final_path[N+1];

bool visited[N];

int final_res = INT_MAX;

void copyToFinal(int curr_path[])


{
for (int i=0; i<N; i++)
final_path[i] = curr_path[i];
final_path[N] = curr_path[0];
}

int firstMin(int adj[N][N], int i)


{
int min = INT_MAX;
for (int k=0; k<N; k++)
if (adj[i][k]<min && i != k)
min = adj[i][k];
return min;
}

int secondMin(int adj[N][N], int i)


{
int first = INT_MAX, second = INT_MAX;
for (int j=0; j<N; j++)
{
if (i == j)
continue;

if (adj[i][j] <= first)


{
second = first;
first = adj[i][j];
}
else if (adj[i][j] <= second &&
adj[i][j] != first)
second = adj[i][j];
}
return second;
}

void TSPRec(int adj[N][N], int curr_bound, int curr_weight,


int level, int curr_path[])
{
if (level==N)
{
if (adj[curr_path[level-1]][curr_path[0]] != 0)
{
int curr_res = curr_weight +
adj[curr_path[level-1]][curr_path[0]];

if (curr_res < final_res)


{
copyToFinal(curr_path);
final_res = curr_res;
}
}
return;
}

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


{
if (adj[curr_path[level-1]][i] != 0 &&
visited[i] == false)
{
int temp = curr_bound;
curr_weight += adj[curr_path[level-1]][i];

if (level==1)
curr_bound -= ((firstMin(adj, curr_path[level-1]) +
firstMin(adj, i))/2);
else
curr_bound -= ((secondMin(adj, curr_path[level-1])
+
firstMin(adj, i))/2);

if (curr_bound + curr_weight < final_res)


{
curr_path[level] = i;
visited[i] = true;

TSPRec(adj, curr_bound, curr_weight, level+1,


curr_path);
}

curr_weight -= adj[curr_path[level-1]][i];
curr_bound = temp;

memset(visited, false, sizeof(visited));


for (int j=0; j<=level-1; j++)
visited[curr_path[j]] = true;
}
}
}

void TSP(int adj[N][N])


{
int curr_path[N+1];

int curr_bound = 0;
memset(curr_path, -1, sizeof(curr_path));
memset(visited, 0, sizeof(curr_path));

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


curr_bound += (firstMin(adj, i) +
secondMin(adj, i));

curr_bound = (curr_bound&1)? curr_bound/2 + 1 :


curr_bound/2;

visited[0] = true;
curr_path[0] = 0;

TSPRec(adj, curr_bound, 0, 1, curr_path);


}

int main()
{
int adj[N][N] = { {0, 10, 15, 20},
{10, 0, 35, 25},
{15, 35, 0, 30},
{20, 25, 30, 0}
};

TSP(adj);

printf("Minimum cost : %d\n", final_res);


printf("Path Taken : ");
for (int i=0; i<=N; i++)
printf("%d ", final_path[i]);

return 0;
}
Output

You might also like