Algorithm[1]
Algorithm[1]
LAB FILE
5.
DAA
2
EMPIRICAL ANALYSIS OF BUBBLE SORT
AIM: To study the change in time of execution as size of input increases and
to plot graph of it
IMPLEMENTATION DETAIL:
1. Execution Time: The code measures the time taken to sort an
array using the bubble sort algorithm. This is done using the time
module.
time_taken = time.time() - time_start: Calculates the
elapsed time by subtracting the start time from the current time
after sorting is completed. This value represents the
execution time of the bubble sort function.
time_start = time.time(): Records the start time before the
sorting begins.
DAA
3
4. Recording Output of Multiple Rows:
The code stores the state of the array after each pass through the
bubble sort algorithm
passes.append(arr[:]): After each pass of the bubble sort, the
current state of the array is appended to the passes list.
arr[:]: Creates a shallow copy of the array arr. This ensures
that each entry in passes is a snapshot of the array at a specific
point in time, preserving the state of the array after each pass.
5. Plotting Graph:
The code can plot a graph to visualize the time complexity of the
bubble sort algorithm for different input sizes:
input_sizes = list(range(500, 4000, 500)): Defines a list
of input sizes, starting from 500 to 3500 with a step of 500.
results = []: Initializes an empty list to store the results.
For each size in input_sizes, the code generates a list of
random numbers, sorts it using bubble sort, and records the time
taken:
sizes, times = zip(*results): Unzips the results into two
separate lists: sizes (input sizes) and times (time taken).
THEORY:
Bubble Sort is the simplest sorting algorithm that works by repeatedly
swapping the adjacent elements if they are in the wrong order
In Bubble Sort algorithm, traverse from left and compare adjacent elements
and the higher one is placed at right side. In this way, the largest element is
moved to the rightmost end at first. This process is then continued to find the
second largest and place it and so on until the data is sorted
CODE:
import random
import time
import matplotlib.pyplot as plt
for i in range(n):
swapped = False
for j in range(0, n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
swapped = True
passes.append(arr[:]) # Store a copy of the array after each pass
if not swapped:
break
def main():
num_inputs = int(input("Enter the number of inputs: "))
if print_random == 'yes':
print("Random numbers before sorting: ", data)
print_passes = input("Do you want to print the array after each pass?
(yes/no): ").strip().lower()
if print_passes == 'yes':
for i, p in enumerate(passes):
print("Pass {}: {}".format(i+1, p))
if plot_graph == 'yes':
input_sizes = list(range(500, 4000, 500))
results = []
plt.figure(figsize=(10, 6))
plt.plot(sizes, times, marker='o')
plt.title('Bubble Sort Time Complexity')
plt.xlabel('Input Array Size')
plt.ylabel('Time Taken (seconds)')
plt.grid(True)
plt.xticks(input_sizes)
plt.show()
if __name__ == "__main__":
main()
OUTPUT:
Enter the number of inputs: 1000
Do you want to print the random numbers before sorting? (yes/no): yes
Random numbers before sorting: [2, 2, 19, 24, 28, 57, 57, 69, 76, 93]
Do you want to print the array after each pass? (yes/no): yes
Pass 1: [2, 24, 69, 2, 28, 57, 19, 76, 57, 93]
Pass 2: [2, 24, 2, 28, 57, 19, 69, 57, 76, 93]
Pass 3: [2, 2, 24, 28, 19, 57, 57, 69, 76, 93]
Pass 4: [2, 2, 24, 19, 28, 57, 57, 69, 76, 93]
Pass 5: [2, 2, 19, 24, 28, 57, 57, 69, 76, 93]
Pass 6: [2, 2, 19, 24, 28, 57, 57, 69, 76, 93]
Do you want to plot the graph for multiple input sizes? (yes/no): yes
DAA
6
CONCLUSION :
As we can see through factual and graphical way , as the size of input
increases, time of execution also increases
Initially the growth was small, but as input size increases, the time of
execution also started increasing rapidly
One more point to be noted is that more precise measurements of time
were given by online compiler for smaller output using same code
From this, we can conclude that as size of input increases, time of
execution also increases
DAA
7
EMPIRICAL ANALYSIS OF LINEAR SEARCH
AIM: To study the change in time of execution as size of input increases and
to plot graph of it
IMPLEMENTATION DETAIL:
1. Dynamic Array:
The dynamic array is created using random.sample, which
generates a list of unique random integers of a specified size. The
array's size is determined at runtime, and the elements are
dynamically generated to ensure they are unique.
3. Execution Time:
The measure_execution_time(arr, target) function calculates
the time taken to perform a linear search on the array.
time.time() function to record the start and end times of the
search, and the difference between these times gives the
execution time.
This execution time is a measure of the algorithm's efficiency for
different scenarios (best case, worst case, and average case).
4. Tabular Data:
show_tabular_form(sizes, best_times, worst_times,
avg_times) function creates a DataFrame from the collected data
and prints it out. This tabular data helps in comparing the
performance across different scenarios and array sizes.
DAA
8
5. Plotting Graph:
plot_results(sizes, best_times, worst_times, avg_times)
function uses Matplotlib to visualize the execution times for best,
worst, and average cases across different array sizes. The graph
plots the array size on the x-axis and the execution time on the y-
axis, with different lines representing best, worst, and average
cases
THEORY:
Linear search is a straightforward algorithm that checks each element in a
list or array sequentially to find a target value. It continues until a match
is found or all elements have been checked. The time complexity of linear
search is O(n), where n is the number of elements.
CODE:
import random
import time
import matplotlib.pyplot as plt
import pandas as pd
def create_dynamic_unique_array(size):
return random.sample(range(size * 2), size)
def main():
sizes = [1000, 2000, 5000, 10000, 20000, 50000]
best_exec_time = []
worst_exec_time = []
average_exec_time = []
DAA
9
best_case_target = arr[0]
best_case_time = measure_execution_time(arr, best_case_target)
best_exec_time.append(best_case_time)
worst_case_target = arr[-1]
worst_case_time = measure_execution_time(arr, worst_case_target)
worst_exec_time.append(worst_case_time)
print(f"Size: {size}")
print(f"Best Case Time: {best_case_time:.6f} seconds")
print(f"Worst Case Time: {worst_case_time:.6f} seconds")
print(f"Average Case Time: {average_case_time:.6f} seconds")
print()
if __name__ == "__main__":
main()
DAA
10
OUTPUT:
DAA
11
EMPIRICAL ANALYSIS OF BINARY SEARCH
AIM: To study the change in time of execution as size of input increases and
to plot graph of it
IMPLEMENTATION DETAIL:
1. Dynamic Array:
The dynamic array is created using random.sample, which
generates a list of unique random integers of a specified size. The
array's size is determined at runtime, and the elements are
dynamically generated to ensure they are unique.
3. Execution Time:
The measure_execution_time(arr, target) function calculates
the time taken to perform a linear search on the array.
time.time() function to record the start and end times of the
search, and the difference between these times gives the
execution time.
This execution time is a measure of the algorithm's efficiency for
different scenarios (best case, worst case, and average case).
4. Tabular Data:
DAA
12
show_tabular_form(sizes, best_times, worst_times,
avg_times) function creates a DataFrame from the collected data
and prints it out. This tabular data helps in comparing the
performance across different scenarios and array sizes.
5. Plotting Graph:
plot_results(sizes, best_times, worst_times, avg_times)
function uses Matplotlib to visualize the execution times for best,
worst, and average cases across different array sizes. The graph
plots the array size on the x-axis and the execution time on the y-
axis, with different lines representing best, worst, and average
cases
THEORY:
Binary search is an efficient algorithm for finding a target value in a sorted
array or list. It works by repeatedly dividing the search interval in half.
Starting with the entire array, the algorithm compares the target value to
the middle element. If the target is equal to the middle element, the
search ends. If the target is less, the search continues in the lower half; if
greater, in the upper half. This process continues until the target is found
or the search interval is empty. Binary search has a time complexity of
O(log n), making it much faster than linear search for large datasets.
CODE:
import time
import random
import matplotlib.pyplot as plt
from tabulate import tabulate
table_data = []
run_number = 1
for size in sizes:
random_array = generate_random_array(size)
random_array.sort()
average_case_time = measure_execution_time(random_array,
random_array[size // 2 + size // 4])
headers = ["Runs", "Size of Array", "Best Case Time (ms)", "Average Case Time
(ms)", "Worst Case Time (ms)"]
print(tabulate(table_data, headers=headers, tablefmt="grid"))
OUTPUT:
DAA
15
IMPLEMENTATION OF GREEDY STRATERGY
TO SOLVE FRACTIONAL KNAPSACK PROBLEM
IMPLEMENTATION DETAIL:
DAA
16
3. Applying Sorting:
CODE:
#include <iostream>
// Swap weights
double tempWeight = weight[j];
weight[j] = weight[j+1];
weight[j+1] = tempWeight;
}
}
}
}
DAA
17
for (int i = 0; i < n; ++i) {
if (weight[i] <= W) {
W -= weight[i];
final_value += profit[i];
fraction[i] = 1.0; // Take the whole item
} else {
fraction[i] = W / weight[i]; // Take a fraction of the item
final_value += profit[i] * fraction[i];
break;
}
}
return final_value;
}
int main() {
double W;
int n;
cout << "Enter the maximum weight capacity of the knapsack: ";
cin >> W;
cout << "\nThe maximum value in the knapsack is: " << max_profit <<
"\n";
DAA
18
cout << "Fraction of each item taken:\n";
for (int i = 0; i < n; ++i) {
cout << "Item " << i+1 << ": " << fraction[i] << "\n";
}
return 0;
}
OUTPUT:
Enter the maximum weight capacity of the knapsack: 20
Enter the number of items: 4
Enter profit for item 1: 10
Enter weight for item 1: 10
Enter profit for item 2: 30
Enter weight for item 2: 15
Enter profit for item 3: 40
Enter weight for item 3: 23
Enter profit for item 4: 40
Enter weight for item 4: 25
DAA
19