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

Ada Assignment

Bubble sort is a simple sorting algorithm where each adjacent pair of elements is compared and elements are swapped if not in order. It has a worst-case time complexity of O(n^2) making it unsuitable for large data sets. Selection sort is another simple sorting algorithm that divides the array into sorted and unsorted parts, selecting the smallest element from the unsorted part and placing it at the start of the sorted part in each iteration. Insertion sort maintains a sorted sub-list, inserting new unsorted items into their correct position in the sub-list one by one. Quicksort uses partitioning and recursive calls to sort sub-arrays, with an average time complexity of O(n^2). Linear search compares each element of a

Uploaded by

tatya tope
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
58 views

Ada Assignment

Bubble sort is a simple sorting algorithm where each adjacent pair of elements is compared and elements are swapped if not in order. It has a worst-case time complexity of O(n^2) making it unsuitable for large data sets. Selection sort is another simple sorting algorithm that divides the array into sorted and unsorted parts, selecting the smallest element from the unsorted part and placing it at the start of the sorted part in each iteration. Insertion sort maintains a sorted sub-list, inserting new unsorted items into their correct position in the sub-list one by one. Quicksort uses partitioning and recursive calls to sort sub-arrays, with an average time complexity of O(n^2). Linear search compares each element of a

Uploaded by

tatya tope
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

Assignment 1: Bubble Sort

Bubble sort is a simple sorting algorithm. This sorting algorithm is


comparison-based algorithm in which each pair of adjacent elements is
compared and the elements are swapped if they are not in order. This
algorithm is not suitable for large data sets as its average and worst case
complexity are of Ο(nn2) where n is the number of items.

✗ Algorithm
Following are the steps involved in bubble sort(nfor sorting a given
array in ascending order):
Step 1: Starting with the first element(nindex = 0), compare the
current element with the next element of the array.
Step 2: If the current element is greater than the next element
of the array, swap them.
Step 3: If the current element is less than the next element,
move to the next element.
Step 4 : Repeat Step 1.

begin BubbleSort(list)
for all elements of list
if list[i] > list[i+1]
swap(list[i], list[i+1])
end if
end for
return list
end BubbleSort
✗ Implementation

class BubbleSort
{
void bubbleSort(int arr[])
{
int n = arr.length;
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}

public static void main(String args[])


{
BubbleSort ob = new BubbleSort();
int arr[] = {64, 34, 25, 12, 22, 11, 90};
ob.bubbleSort(arr);
System.out.println("Sorted array");
ob.printArray(arr);
}}

Output:
Sorted array:
11 12 22 25 34 64 90
Assignment 2: Selection Sort
Selection sort is a simple sorting algorithm. This sorting algorithm is an in-
place comparison-based algorithm in which the list is divided into two
parts, the sorted part at the left end and the unsorted part at the right end.
Initially, the sorted part is empty and the unsorted part is the entire list.
The smallest element is selected from the unsorted array and swapped with
the leftmost element, and that element becomes a part of the sorted array.
This process continues moving unsorted array boundary by one element to
the right.
This algorithm is not suitable for large data sets as its average and worst
case complexities are of Ο(nn2), where n is the number of items.

✗ Algorithm
Following are the steps involved in selection sort(nfor sorting a given
array in ascending order):
Step 1: Starting from the first element, we search the smallest
element in the array, and replace it with the element in the first
position.
Step 2 : We then move on to the second position, and look for
smallest element present in the subarray, starting from index 1, till
the last index.
Step 3 : We replace the element at the second position in the original
array, or we can say at the first position in the subarray, with the
second smallest element.
Step 4: This is repeated, until the array is completely sorted.
✗ Implementation

class SelectionSort
{
void sort(int arr[])
{
int n = arr.length;
for (int i = 0; i < n-1; i++)
{
int min_idx = i;
for (int j = i+1; j < n; j++)
if (arr[j] < arr[min_idx])
min_idx = j;
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i]+" ");
System.out.println();
}
public static void main(String args[])
{
SelectionSort ob = new SelectionSort();
int arr[] = {64,25,12,22,11};
ob.sort(arr);
System.out.println("Sorted array");
ob.printArray(arr);
}}

Output:
Sorted array:
11 12 22 25 64
Assignment 3: Insertion Sort
This is an in-place comparison-based sorting algorithm. Here, a sub-list is
maintained which is always sorted. For example, the lower part of an array
is maintained to be sorted. An element which is to be 'insert'ed in this
sorted sub-list, has to find its appropriate place and then it has to be
inserted there. Hence the name, insertion sort.
The array is searched sequentially and unsorted items are moved and
inserted into the sorted sub-list (nin the same array). This algorithm is not
suitable for large data sets as its average and worst case complexity are of
Ο(nn2), where n is the number of items.

✗ Algorithm
Following are the steps involved in insertion sort:

Step 1 : We start by making the second element of the given array, i.e.
element at index 1, the key. The key element here is the new card that
we need to add to our existing sorted set of cards(nremember the
example with cards above).
Step 2 : We compare the key element with the element(ns) before it, in
this case, element at index 0:
•If the key element is less than the first element, we insert the key
element before the first element.
•If the key element is greater than the first element, then we insert it
after the first element.
Step 3 : Then, we make the third element of the array as key and will
compare it with elements to it's left and insert it at the right position.
Step 4 : And we go on repeating this, until the array is sorted.
✗ Implementation

class InsertionSort {
void sort(int arr[])
{
int n = arr.length;
for (int i = 1; i < n; ++i) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
static void printArray(int arr[])
{
int n = arr.length;
for (int i = 0; i < n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}
public static void main(String args[])
{
int arr[] = { 12, 11, 13, 5, 6 };

InsertionSort ob = new InsertionSort();


ob.sort(arr);

printArray(arr);
}

Output :

5 6 11 12 13
Assignment 4: Quick Sort
Quick sort is a highly efficient sorting algorithm and is based on
partitioning of array of data into smaller arrays. A large array is partitioned
into two arrays one of which holds values smaller than the specified value,
say pivot, based on which the partition is made and another array holds
values greater than the pivot value.
Quick sort partitions an array and then calls itself recursively twice to sort
the two resulting subarrays. This algorithm is quite efficient for large-sized
data sets as its average and worst case complexity are of Ο(nn 2), where n is
the number of items.

✗ Algorithm

Based on our understanding of partitioning in quick sort, we will now try


to write an algorithm for it, which is as follows.

Step 1 : Choose the highest index value has pivot


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

class QuickSort
{
int partition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low-1); // index of smaller element
for (int j=low; j<high; j++)
{
if (arr[j] <= pivot)
{
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i+1];
arr[i+1] = arr[high];
arr[high] = temp;
return i+1;
}
void sort(int arr[], int low, int high)
{
if (low < high)
{
int pi = partition(arr, low, high);
sort(arr, low, pi-1);
sort(arr, pi+1, high);
}
}
static void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i]+" ");
System.out.println();
}
public static void main(String args[])
{
int arr[] = {10, 7, 8, 9, 1, 5};
int n = arr.length;

QuickSort ob = new QuickSort();


ob.sort(arr, 0, n-1);

System.out.println("sorted array");
printArray(arr);
}
}

Output :

Sorted array:
1 5 7 8 9 10
Assignment 5: Linear Search
Linear search is a very simple search algorithm. In this type of search, a
sequential search is made over all items one by one. Every item is checked
and if a match is found then that particular item is returned, otherwise the
search continues till the end of the data collection.

✗ Algorithm
Linear Search (n Array A, Value x)
Step 1 : Set i to 1
Step 2 : if i > n then go to step 7
Step 3 : if A[i] = x then go to step 6
Step 4 : Set i to i + 1
Step 5 : Go to Step 2
Step 6 : Print Element x Found at index i and go to step 8
Step 7 : Print element not found
Step 8 : Exit

✗ Implementation

class LinearSearch
{
public static int search(int arr[], int x)
{
int n = arr.length;
for(int i = 0; i < n; i++)
{
if(arr[i] == x)
return i;
}
return -1;
}
public static void main(String args[])
{
int arr[] = { 2, 3, 4, 10, 40 };
int x = 10;

int result = search(arr, x);


if(result == -1)
System.out.print("Element is not present in array");
else
System.out.print("Element is present at index " + result);
}}
Output :
Element is present at index 3
Assignment 6: Binary Search
Binary search is a fast search algorithm with time complexity of Ο(nlog n).
This search algorithm works on the principle of divide and conquer. For
this algorithm to work properly, the data collection should be in the sorted
form.
Binary search looks for a particular item by comparing the middle most
item of the collection. If a match occurs, then the index of item is returned.
If the middle item is greater than the item, then the item is searched in the
sub-array to the left of the middle item. Otherwise, the item is searched for
in the sub-array to the right of the middle item. This process continues on
the sub-array as well until the size of the subarray reduces to zero.

✗ Algorithm
Following are the steps of implementation that we will be following:
Step 1 : Start with the middle element:
➢If the target value is equal to the middle element of the array, then
return the index of the middle element.
➢If not, then compare the middle element with the target value,
✔If the target value is greater than the number in the middle
index, then pick the elements to the right of the middle index, and
start with Step 1.
✔If the target value is less than the number in the middle index,
then pick the elements to the left of the middle index, and start
with Step 1.
Step 2 : When a match is found, return the index of the element
matched.
Step 3 : If no match is found, then return -1.
✗ Implementation
class BinarySearch {
int binarySearch(int arr[], int l, int r, int x)
{
if (r >= l) {
int mid = l + (r - l) / 2;
if (arr[mid] == x)
return mid;
if (arr[mid] > x)
return binarySearch(arr, l, mid - 1, x);
return binarySearch(arr, mid + 1, r, x);
}
return -1; }
public static void main(String args[])
{ BinarySearch ob = new BinarySearch();
int arr[] = { 2, 3, 4, 10, 40 };
int n = arr.length;
int x = 10;
int result = ob.binarySearch(arr, 0, n - 1, x);
if (result == -1)
System.out.println("Element not present");
else
System.out.println("Element found at index " + result); } }
Output:
Element is present at index 3
Assignment 7:
Matrix Chain Multiplication

If a chain of matrices is given, we have to find the minimum number of the


correct sequence of matrices to multiply.
We know that the matrix multiplication is associative, so four matrices
ABCD, we can multiply A(nBCD), (nAB)(nCD), (nABC)D, A(nBC)D, in these
sequences. Like these sequences, our task is to find which ordering is
efficient to multiply.

✗ 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
✗ Implementation
class MatrixChainMultiplication
{ static int MatrixChainOrder(int p[], int i, int j)
{ if (i == j)
return 0;
int min = Integer.MAX_VALUE;
for (int k=i; k<j; k++)
{ int count = MatrixChainOrder(p, i, k) +
MatrixChainOrder(p, k+1, j) + p[i-1]*p[k]*p[j];
if (count < min)
min = count;
}
return min;
}
public static void main(String args[])
{
int arr[] = new int[] {1, 2, 3, 4, 3};
int n = arr.length;
System.out.println("Minimum number of multiplications is "+
MatrixChainOrder(arr, 1, n-1)); } }

Output :
Minimum number of multiplications is 30
Assignment 8 : Knapsack Problem

Given a set of items, each with a weight and a value, determine a subset of
items to include in a collection so that the total weight is less than or equal
to a given limit and the total value is as large as possible.
The knapsack problem is in combinatorial optimization problem. It
appears as a subproblem in many, more complex mathematical models of
real-world problems. One general approach to difficult problems is to
identify the most restrictive constraint, ignore the others, solve a knapsack
problem, and somehow adjust the solution to satisfy the ignored
constraints.

✗ Algorithm: Fractinal 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] = (nW - weight) / w[i]
weight = W
break
return x
✗ Implementation
import java.util.Arrays;
import java.util.Comparator;
public class FractionalKnapSack
{
public static void main(String[] args) {
int[] wt = {10, 40, 20, 30};
int[] val = {60, 40, 100, 120};
int capacity = 50;
double maxValue = getMaxValue(wt, val, capacity);
System.out.println("Maximum value we can obtain = " +
maxValue);
}
private static double getMaxValue(int[] wt,
int[] val, int capacity)
{
ItemValue[] iVal = new ItemValue[wt.length];

for(int i = 0; i < wt.length; i++)


{
iVal[i] = new ItemValue(wt[i], val[i], i);
}
Arrays.sort(iVal, new Comparator<ItemValue>()
{
@Override
public int compare(ItemValue o1, ItemValue o2)
{
return o2.cost.compareTo(o1.cost) ;
}
});

double totalValue = 0d;


for(ItemValue i: iVal)
{ int curWt = (int) i.wt;
int curVal = (int) i.val;
if (capacity - curWt >= 0)
{ capacity = capacity-curWt;
totalValue += curVal;
}
else
{ double fraction =
((double)capacity/(double)curWt);
totalValue += (curVal*fraction);
capacity = (int)(capacity - (curWt*fraction));
break; } }
return totalValue;
}
static class ItemValue
{ Double cost;
double wt, val, ind;
public ItemValue(int wt, int val, int ind)
{ this.wt = wt;
this.val = val;
this.ind = ind;
cost = new Double(val/wt ); } } }
Output :
Maximum value in Knapsack = 240
Assignment 9 : 4-Queens Problem

This problem is to find an arrangement of 4 queens on a chess board, such


that no queen can attack any other queens on the 4×4 board.
The chess queens can attack in any direction as horizontal, vertical,
horizontal and diagonal way.
A binary matrix is used to display the positions of 4 Queens, where no
queens can attack other queens.

✗ Algorithm

Step 1 : Start in the leftmost column


Step 2 : If all queens are placed return true
Step 3 : Try all rows in the current column. Do following for every
tried row.
a) If the queen can be placed safely in this row then mark this
[row, column] as part of the solution and recursively check if
placing queen here leads to a solution.
b) If placing the queen in [row, column] leads to a solution then
return true.
c) If placing queen doesn't lead to a solution then umark this
[row, column] (nBacktrack) and go to step (na) to try other rows.
Step 4 : If all rows have been tried and nothing worked, return false
to trigger backtracking.
✗ Implementation
public class NQueenProblem
{ final int N = 4;
void printSolution(int board[][])
{ for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
System.out.print(" " + board[i][j] + " ");
System.out.println(); } }
boolean isSafe(int board[][], int row, int col){
int i, j;
for (i = 0; i < col; i++)
if (board[row][i] == 1)
return false;
for (i=row, j=col; i>=0 && j>=0; i--, j--)
if (board[i][j] == 1)
return false;
for (i=row, j=col; j>=0 && i<N; i++, j--)
if (board[i][j] == 1)
return false;
return true; }
boolean solveNQUtil(int board[][], 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) == true)
return true;
board[i][col] = 0; } }
return false; }
boolean solveNQ() {
int board[][] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0} };
if (solveNQUtil(board, 0) == false) {
System.out.print("Solution does not exist");
return false; }
printSolution(board);
return true; }
public static void main(String args[]) {
NQueenProblem Queen = new NQueenProblem();
Queen.solveNQ(); } }

Output :
0010
1000
0001
0100
Assignment 10 :
Dynamic Programming
Dynamic programming approach is similar to divide and conquer in
breaking down the problem into smaller and yet smaller possible sub-
problems. But unlike, divide and conquer, these sub-problems are not
solved independently. Rather, results of these smaller sub-problems are
remembered and used for similar or overlapping sub-problems.
Dynamic programming is used where we have problems, which can be
divided into similar sub-problems, so that their results can be re-used.
Mostly, these algorithms are used for optimization. Before solving the in-
hand sub-problem, dynamic algorithm will try to examine the results of the
previously solved sub-problems. The solutions of sub-problems are
combined in order to achieve the best solution.
So we can say that −

➢ The problem should be able to be divided into smaller overlapping


sub-problem.
➢ An optimum solution can be achieved by using an optimum solution
of smaller sub-problems.
➢ Dynamic algorithms use Memoization.

In contrast to greedy algorithms, where local optimization is addressed,


dynamic algorithms are motivated for an overall optimization of the
problem.
In contrast to divide and conquer algorithms, where solutions are
combined to achieve an overall solution, dynamic algorithms use the
output of a smaller sub-problem and then try to optimize a bigger sub-
problem. Dynamic algorithms use Memoization to remember the output of
already solved sub-problems.
✗ Examples
1. 0/1 Knapsack Problem
Given weights and values of n items, put these items in a
knapsack of capacity W to get the maximum total value in the
knapsack. In other words, given two integer arrays val[0..n-1]
and wt[0..n-1] which represent values and weights associated
with n items respectively. Also given an integer W which
represents knapsack capacity, find out the maximum value
subset of val[] such that sum of the weights of this
subset is smaller than or equal to W. You cannot break an item,
either pick the complete item, or don’t pick it (n0-1 property).
Let i be the highest-numbered item in an optimal solution S for
W dollars. Then S' = S - {i} is an optimal solution for W - wi
dollars and the value to the solution S is Vi plus the value of the
sub-problem. We can express this fact in the following formula:
define c[i, w] to be the solution for items 1,2, … , i and the
maximum weight w. The algorithm takes the following inputs
• The maximum weight W
• The number of items n
• The two sequences v = <v1,.., vn> and w = <w1,.., wn>
for w = 0 to W do
c[0, w] = 0
for i = 1 to n do
c[i, 0] = 0
for w = 1 to W do
if wi ≤ w then
if vi + c[i-1, w-wi] then
c[i, w] = vi + c[i-1, w-wi]
else c[i, w] = c[i-1, w]
else
c[i, w] = c[i-1, w]
2. All Pair Shortest Path by Floyd-Warshall
Floyd-Warshall's algorithm is based upon the observation that a path
linking any two vertices and may have zero or more intermediate vertices.
The algorithm begins by disallowing all intermediate vertices. In this case,
the partial solution is simply the initial weights of the graph or infinity if
there is no edge.
The algorithm proceeds by allowing an additional intermediate vertex at
each step. For each introduction of a new intermediate vertex, the shortest
path between any pair of vertices and, is the minimum of the previous best
estimate of, or the combination of the paths from and.

Let the directed graph be represented by a weighted matrix W.

Algorithm
FLOYD-WARSHALL (W)
1 n ← rows [W]
2 D(0) ← W
3 for k ← 1 to n
4 do for i ← 1 to n
5 do for j ← 1 to n
6 do dij (k) ← MIN ( dij (k-1) , dik (k-1) + dkj (k-1) )
7 return D(n)

The time complexity of the algorithm above is O(nn3).

You might also like