Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

design assignment

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 15

ADAMA SCIENCE AND TECHNOLOGY

UNIVERSITY

Computer Science and Engineering

Design and Analysis of Algorithms [CSEg2208]: Assignment1

Individual assignment 1
Name;- Guda Tiruneh
Id no;- ugr/30603/15

Submitted to: instructor:


Submission date: Tuesday,sept19

1
Question no1

An algorithm is a methodical process or a collection of instructions that a computer or


other computing device can use to carry out a certain task or solve a particular issue.
The essential components of computer programming, algorithms are necessary for
effective problem-solving. The following are the main attributes of algorithms:
1.Definiteness: A well-defined, unambiguous algorithm is necessary. There must be
no room for interpretation and the instructions must be very clear.
2.Input: In order to carry out the required calculations or operations, algorithms
usually require one or more inputs, which can be data, values, or parameters.
3.Output: The answers or solutions to the problems that algorithms are meant to solve
are generated by one or more of these outputs.
3.Finiteness: The number of steps in an algorithm must be finite.
4. Generality: Algorithms should be designed to handle a class of problems, not just
a specific instance. They should be applicable to a wide range of input and scenarios.
5. Simplicity: Algorithms should be as simpler and straightforward possible,making
them easier them easier to understand ,analyze and implement .
6. Modularity : Algorithm can be broken down into smaller,reusable components or
sub-algorithms, making them them more salable and maintainable.

Question No2

There are several ways to represent an algorithm,each with its own advantages and
disadvantages. Here’s a breakdown of common methods

1. Natural language:
. Description: This is the most intuitive way to describe an algorithm. You use
plain English(or any other natural language)to explain the steps involved.
. Advantages: Easy to understand for humans , especially for the beginners.
.Disadvantages: can be ambiguous,prone to errors,and difficult to translate into
code.

2. Flowchart:

2
. Discription :Uses graphical symbols to represent the steps and flow an algorithm.
. Advantages: Visualiy appealing, easy to follow the logic, good for illustrating
complex algorithms.
. Disadvantages: can be cumbersome for large algorithms, not suitable for complex
data structures.
3. Psedocode:
. Description: A structured , high-level description of an algorithm using a
combination of natural language and programming constructs.
. Advantages: More precise than natural language,easier to translate into code,good
for communicating algorithm to programmers.
. Disadvantages: Can be less intuitive for beginners, requires some understanding
of programming concepts.

4. programming Language:
. Description: The most concrete way to represent an algorithm. You write the
algorithm using a specific programming language.
. Advantages: Directly executable, can be tested and debugged, allows for efficient
implementation.
. Disadvantages: Requires knowledge of a programming language, can be less
readable for non-programmers.

The best way to represent an algorithm depends on the specific algorithm, the
intended audience , and the purpose of the representation. For simple algorithms,
natural language or flowcharts may suffice. For more complex algorithm, psedocode
or programming language may be more appropriate. Decision table can be useful for
algorithms with multiple conditions and actions.

Question no 3
The analysis of algorithm can be broadly categorized into tow approaches:prior
(theoretical) analysis and posterior (empirical) analysis. Here’s a breakdown of their
Key differences:

Prior(Theoretical) Analysis:

3
. Focus ; Analyzes the algorithm’s performance based on its mathematical
description and assumption about the input data.
.Methods: uses mathematical tools like Big O notation, recurrence relations , and
complexity analysis to estimate the algorithm’s time and space complexity.
. Advantages: Provides a general understanding of the algorithm’s efficiency ,
independent of specific inputs. Useful for comparing algorithm and predicting their
performance on large datasets.
. Disadvantages: can be overlay optimistic, as it doesn’t account for a real-world
factors like hardware limitations, specific input distribution , and implementation
details.

Posterior(Empirical) Analysis:
. Focus: Evaluates the algorithm’s performance based in actual execution on real-
world data.
. Methods: Involves running the algorithm with different inputs, measuring its
execution time, memory usage, and other performance metrics.
. Advantages: provides a realistic assessment of the algorithm’s performance in
specific scenarios. Useful for fine-tuning algorithms and identifying bottlenecks.
. Disadvantages: Results can be specific to the test data and hardware used. May not
generalize well to other datasets or environments.

In conclusion:
Both prior and posterior analyses are valuable for understanding and optimizing
algorithms. Theoretical analysis provides a general framework, while empirical analy
sis provides real-world insights. Combining both approaches offers a comprehensive
understanding of an algorithm’s performance .

Question no 4
Asymptotic analysis is a way to evaluate the performance and efficiency of algorithms
by studying how they behave as the size of the input gets larger and larger. It focuses

4
on understanding the upper limit, lower limit, and average-case behavior of an
algorithm's time and space complexity.

The different asymptotic notations are used to describe these limits:

1. **Big O Notation (O)**: This represents the upper bound, the worst-case scenario.
It tells us how fast the algorithm's resource consumption (like running time) can grow
at most as the input size increases.
Example: If an algorithm has a time complexity of O(n^2), it means the running
time will grow no faster than a quadratic function of the input size.

2. **Omega Notation (Ω)**: This represents the lower bound, the best-case scenario.
It tells us how fast the algorithm's resource consumption can grow at least as the input
size increases.
Example: If an algorithm has a time complexity of Ω(n), it means the running time
will grow at least linearly with the input size.

3. **Theta Notation (Θ)**: This represents the tight bound, the average-case
scenario. It tells us how fast the algorithm's resource consumption will grow, with
both an upper and lower limit.
Example: If an algorithm has a time complexity of Θ(n log n), it means the running
time will grow at a rate that is both upper and lower bounded by a constant multiple
of n log n.

4. **Little o Notation (o)**: This represents an upper bound that is strictly less than
the given function. It describes an even better asymptotic behavior than the given
function.
Example: If an algorithm has a time complexity of o(n^2), it means the running time
will grow strictly slower than a quadratic function of the input size.

5. **Little ω Notation (ω)**: This represents a lower bound that is strictly greater
than the given function. It describes an even worse asymptotic behavior than the given
function.

5
Example: If an algorithm has a time complexity of ω(n), it means the running time
will grow strictly faster than a linear function of the input size.

These asymptotic notations provide a concise and standardized way to analyze and
compare the efficiency of different algorithms, without getting into the specifics of
their implementations. This is a valuable tool in computer science and algorithm
design for making informed decisions about choosing and optimizing algorithms.

Question no 5

Sure, let's discuss the following data structures in detail:

a. **Array**:
- An array is a collection of elements of the same data type, stored in contiguous
memory locations.
- Elements in an array are accessed using an index, which is a non-negative integer
that represents the position of the element within the array.
- Arrays have a fixed size, which means that the number of elements that can be
stored in an array is determined when the array is created and cannot be changed later.
- Arrays provide constant-time access to elements (O(1) time complexity) using the
index, but insertion and deletion operations can be expensive (O(n) time complexity)
if they require shifting other elements.
- Arrays are commonly used for storing and manipulating data that can be easily
indexed, such as numerical data, strings, and other homogeneous data types.

b. **Linked List**:
- A linked list is a dynamic data structure that consists of a sequence of nodes,
where each node contains a data value and a reference (or link) to the next node in the
sequence.
- Linked lists do not have a fixed size, and the number of elements can be changed
dynamically during runtime.

6
- Accessing an element in a linked list has a time complexity of O(n), as the
algorithm needs to traverse the list from the beginning to the desired element.
- Insertion and deletion operations in a linked list can be efficient (O(1) time
complexity) if the location of the operation is known.
- Linked lists are commonly used for implementing other data structures, such as
stacks, queues, and deques, as well as for representing data that requires frequent
insertion and deletion operations.

c. **Stack**:
- A stack is a Last-In-First-Out (LIFO) data structure, which means that the last
element added to the stack is the first one to be removed.
- Stacks support three main operations: push (add an element to the top of the
stack), pop (remove the top element from the stack), and peek (return the top element
without removing it).
- Accessing and manipulating the top element of a stack has a time complexity of
O(1), making it an efficient data structure for certain algorithms and applications.
- Stacks are commonly used for managing function calls, expression evaluation, and
backtracking algorithms, as well as for implementing undo/redo functionality in
software applications.

d. **Queue**:
- A queue is a First-In-First-Out (FIFO) data structure, which means that the first
element added to the queue is the first one to be removed.
- Queues support three main operations: enqueue (add an element to the back of the
queue), dequeue (remove the element from the front of the queue), and peek (return
the element at the front of the queue without removing it).
- Accessing and manipulating the front and back elements of a queue has a time
complexity of O(1), making it an efficient data structure for certain algorithms and
applications.
- Queues are commonly used for managing tasks, processes, and events in a
sequential manner, such as in job scheduling, resource allocation, and network traffic
management.

e. **Binary Tree and Binary Search Tree**:

7
- A binary tree is a tree-based data structure where each node has at most two child
nodes, referred to as the left child and the right child.
- A binary search tree (BST) is a specialized form of a binary tree where the values
in the left subtree of a node are less than the value of the node, and the values in the
right subtree are greater than the value of the node.
- Searching, insertion, and deletion operations in a binary search tree have an
average time complexity of O(log n), where n is the number of nodes in the tree,
making them efficient for many applications.
- Binary trees and binary search trees are commonly used in various algorithms and
applications, such as file systems, database indexing, and decision-making processes.

f. **Graph**:
- A graph is a non-linear data structure that consists of a set of nodes (or vertices)
and a set of edges that connect these nodes.
- Graphs can be directed (where the edges have a specific direction) or undirected
(where the edges have no specific direction).
- Graphs can be used to represent a wide variety of real-world relationships and
structures, such as social networks, transportation networks, and computer networks.
- Common graph-related operations include traversal (e.g., depth-first search,
breadth-first search), finding the shortest path between two nodes, and detecting
connected components.
- The time complexity of graph algorithms can vary depending on the specific
problem and the representation of the graph (e.g., adjacency matrix, adjacency list).
- Graphs are widely used in various applications, such as social network analysis,
route planning, and recommendation systems.

These data structures have different strengths, weaknesses, and use cases, and
understanding their properties and performance characteristics is crucial for designing
efficient algorithms and solving complex problems in computer science.

Question No 6

8
The brute force approach is a straightforward problem-solving technique that involves
trying all possible solutions until the correct one is found. Here are the advantages and
disadvantages of the brute force approach for algorithm design:

Advantages:

1. **Simplicity**: The brute force approach is relatively simple to understand and


implement, as it does not require advanced algorithmic techniques or data structures.

2. **Guaranteed solution**: If a solution exists, the brute force approach will


eventually find it, as it systematically checks all possible solutions.

3. **Applicability**: The brute force approach can be applied to a wide range of


problems, from simple to complex, as long as the problem space is small enough to be
exhaustively searched.

4. **Ease of implementation**: Brute force algorithms are often easier to implement


than more sophisticated algorithms, as they do not require complex data structures or
intricate logic.

Disadvantages:

1. **Time complexity**: The brute force approach typically has a high time
complexity, often growing exponentially or factorially with the size of the input. This
makes it inefficient for solving large-scale problems.

2. **Space complexity**: Brute force algorithms may require a large amount of


memory to store intermediate results or the entire solution space, which can be a
problem for problems with large input sizes.

3. **Lack of optimality**: The brute force approach does not necessarily find the
optimal solution, as it simply checks all possible solutions without considering any
optimization strategies.

9
4. **Inefficiency for large problem spaces**: As the problem size increases, the brute
force approach quickly becomes impractical or even infeasible, as the number of
possible solutions grows exponentially.

5. **Limited scalability**: Brute force algorithms often do not scale well to larger
input sizes, as their running time increases rapidly with the problem size.

The brute force approach is often used as a starting point for solving problems,
particularly when the problem space is small enough to be exhaustively searched.
However, for larger and more complex problems, more efficient algorithms that
exploit problem-specific structures or use advanced techniques are generally
preferred.

Question No 7
a. **Searching for an element from a list of arrays**:

```cpp
#include <iostream>
#include <vector>

bool searchElement(const std::vector<std::vector<int>>& arrList, int target) {


for (const auto& arr : arrList) {
for (int element : arr) {
if (element == target) {
return true;
}
}
}
return false;
}

int main() {
std::vector<std::vector<int>> arrList = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

10
int target = 5;
if (searchElement(arrList, target)) {
std::cout << "Element found!" << std::endl;
} else {
std::cout << "Element not found." << std::endl;
}
return 0;
}
```

Efficiency Analysis:
- Time Complexity: O(n * m), where n is the number of arrays in the list and m is the
maximum size of any array.
- Space Complexity: O(1), as the algorithm only uses a constant amount of extra
space.

b. **Checking whether a set is a subset of another set or not**:

```cpp
#include <iostream>
#include <unordered_set>

bool isSubset(const std::unordered_set<int>& set1, const std::unordered_set<int>&


set2) {
for (int element : set1) {
if (set2.find(element) == set2.end()) {
return false;
}
}
return true;
}

int main() {
std::unordered_set<int> set1 = {1, 2, 3};

11
std::unordered_set<int> set2 = {1, 2, 3, 4, 5};
if (isSubset(set1, set2)) {
std::cout << "Set1 is a subset of Set2." << std::endl;
} else {
std::cout << "Set1 is not a subset of Set2." << std::endl;
}
return 0;
}
```

Efficiency Analysis:
- Time Complexity: O(n * m), where n is the size of `set1` and m is the size of `set2`.
- Space Complexity: O(1), as the algorithm only uses a constant amount of extra
space.

c. **Selection Sort**:

```cpp
#include <iostream>
#include <vector>

std::vector<int> selectionSort(std::vector<int>& arr) {


int n = arr.size();
for (int i = 0; i < n; i++) {
int minIdx = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIdx]) {
minIdx = j;
}
}
std::swap(arr[i], arr[minIdx]);
}
return arr;
}

12
int main() {
std::vector<int> arr = {5, 2, 8, 1, 9};
std::vector<int> sortedArr = selectionSort(arr);
for (int num : sortedArr) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
```

Efficiency Analysis:
- Time Complexity: O(n^2), where n is the size of the input array.
- Space Complexity: O(1), as the algorithm performs the sorting in-place.

d. **String Matching Problem**:

```cpp
#include <iostream>
#include <string>

int stringMatch(const std::string& text, const std::string& pattern) {


int n = text.length();
int m = pattern.length();
for (int i = 0; i <= n - m; i++) {
if (text.substr(i, m) == pattern) {
return i;
}
}
return -1;
}

int main() {

13
std::string text = "Hello, world!";
std::string pattern = "world";
int index = stringMatch(text, pattern);
if (index == -1) {
std::cout << "Pattern not found." << std::endl;
} else {
std::cout << "Pattern found at index: " << index << std::endl;
}
return 0;
}
```

Efficiency Analysis:
- Time Complexity: O(n * m), where n is the length of the text and m is the length of
the pattern.
- Space Complexity: O(1), as the algorithm only uses a constant amount of extra
space.

References :
 Course Textbook(Introduction to the design and analysis of algorithms, Anany
levitin 2013).
 http:// www.rabieramadan.org

14
 http://www.tutorialspoint.com/python/

15

You might also like