Dmada
Dmada
UNIT-1:
Q1.What is an algorithm ?what do you mean
by correct algorithm ? What do you mean by
intance of a problem ?list out the criteria
that all algorithms must satisfy . On what
bases will you consider algorithm A is a
better than algorithm B?
Ans:
- Algorithm: A step-by-step procedure to
solve a problem or perform a task.
Ax + b = 0
Ax + b \geq c
4. Asymptotic Notation: Asymptotic
notation describes the behavior of an
algorithm as its input size approaches
infinity. The three common types are:
Example:
Consider an algorithm that runs in .
The Big-O is , focusing on the dominant term
as , which is .
Accounting Method:
Aggregate Analysis:
2. Relation:
Example:
Let and .
A relation can be: .
3. Function:
Example:
Is a function mapping to .
2. Accounting Method:
Overcharge cheaper operations and store
“credits” to pay for more expensive
operations later.
3. Potential Method:
Uses a potential function to represent the
stored work (like credits) and tracks changes
in potential to balance expensive
operations.
Aggregate Analysis for a k-bit Binary
Counter:
3.Big O Notation
Big O notation expresses the upper
bound of an algorithm’s time or space
complexity, representing its performance
in the worst case as input size grows.
, , and .
.
T(n) = \Theta(n^3)
Unit-1:
Q1. What is an algorithm? Explain various
properties of an algorithm.
An algorithm is a step-by-step procedure or
set of rules designed to perform a specific
task or solve a problem. It is a sequence of
instructions that, when followed, leads to
the desired output for a given input.
Properties of an Algorithm:
1. Finiteness: An algorithm must have
a finite number of steps, meaning it
should terminate after a set number of
operations.
2. Definiteness: Each step of the
algorithm must be clear and
unambiguous, with no uncertainty in
what to do at any stage.
3. Input: An algorithm should have
well-defined inputs, which may be zero
or more values provided before
execution.
4. Output: The algorithm must produce
at least one output, which is the result of
the computations performed on the
input.
5. Effectiveness: The steps of the
algorithm must be basic enough to be
performed by a person or machine
within a reasonable time, using basic
operations.
6. Deterministic: The algorithm should
produce the same output for the same
input each time it is executed, without
randomness (unless it's a probabilistic
algorithm).
7. Generality: An algorithm should be
applicable to a set of inputs, not just a
specific problem instance, providing a
general solution for a class of problems.
# Example usage:
arr = [64, 25, 12, 22, 11]
sorted_arr = selection_sort(arr)
print(sorted_arr) # Output: [11, 12, 22, 25,
64]
# Example usage:
n = 3 # Number of disks
tower_of_hanoi(n, 'A', 'C', 'B')
# Example usage:
word = "DESIGN"
sorted_word = ''.join(bubble_sort(list(word)))
print(sorted_word) # Output: DEGISN
# Example usage:
word = "EDUCATION"
sorted_word = ''.join(sorted(word)) # or use
insertion_sort(list(word))
insertion_sort(list(word))
print(''.join(word)) # Output: "ACDEIOTU"
# Example usage:
letters = ['U', 'N', 'I', 'V', 'E', 'R', 'S']
bubble_sort(letters)
sorted_letters = ''.join(letters)
print(sorted_letters) # Output: "EINRSUV"
Result:
The letters sorted in alphabetical order are:
"EINRSUV".
Unit-2
Q1. Prove that Greedy Algorithms does not
always give optimal solution. What are the
general characteristics of Greedy
Algorithms? Also compare GreedyAlgorithms
with Dynamic Programming and Divide and
Conquer methods to find out major
difference between them.
Greedy Algorithm Suboptimality Proof:
0/1 Knapsack Example:
Items: (Weight, Value) = (10, 60), (20,
100), (30, 120)
Knapsack capacity = 50
Greedy by value/weight picks Item 3 (ratio =
4), leaving 20 capacity but suboptimal total
value of 180. Optimal solution: pick Items 1
and 2, total value = 160.
Thus, greedy may not always give the
optimal solution.
Comparison:
Dynamic Divide
Greed
Aspect Programmi and
y
ng Conquer
Solve all Divide into
Locally
Approach subproblem independe
optimal
s nt parts
Yes
Backtracki
None (memoizatio Sometimes
ng
n)
Varies
Complexit Often O(n^2) or (depends
y O(n) more on
problem)
Prim's, Merge
Knapsack,
Examples Kruskal' Sort, Quick
Fibonacci
s Sort
Greedy: Fast, may not be optimal.
Dynamic Programming: Slower,
always optimal.
Divide and Conquer: Splits problems
into subproblems, optimal in certain
cases.
Q2. Justify the general statement
that “if a problem can be split using
Divide and Conquer strategy in
almost equal portions at each stage,
then it is a good can did ate for
recursive implementation, but if it
cannot be easily be so divided in
equal portions, then it better be
implemented iteratively”. Explain
with an example.
The Divide and Conquer strategy
works well when a problem can be split
into almost equal portions because
recursion efficiently handles these
balanced subproblems. However, if the
portions are uneven, recursion can lead
to inefficiency due to unbalanced call
stacks and unnecessary recomputation.
In such cases, an iterative approach is
often better, as it avoids the overhead of
recursion.
Example:
1. Merge Sort (Balanced) –
Recursive:
o Splits the array into two nearly equal
halves at each step.
o Recursion handles the two halves
efficiently, leading to O(n log n)
time complexity.
2. Fibonacci Sequence
(Unbalanced) – Iterative:
o Recursive version recalculates
overlapping subproblems, leading to
exponential time complexity
(O(2^n)).
o Iterative version runs in O(n) time by
avoiding redundant calculations.
Thus, recursion fits well for balanced
problems (like Merge Sort), while
iterative methods are better for
unbalanced problems (like Fibonacci).
⋅y0
1. z0=x0⋅y0z_0 = x_0 \cdot y_0z0=x0
2. z1=(x1+x0)⋅(y1+y0)z_1 = (x_1 +
x_0) \cdot (y_1 + y_0)z1=(x1+x0)⋅(y1
+y0)
⋅y1
3. z2=x1⋅y1z_2 = x_1 \cdot y_1z2=x1
# Example Usage
arr = [50, 40, 20, 60, 80, 100, 45, 70, 105,
30, 90, 75]
quicksort(arr, 0, len(arr) - 1)
print(arr) # Sorted array: [20, 30, 40, 45,
50, 60, 70, 75, 80, 90, 100, 105]
Analysis
Example:
Array =
[50,40,20,60,80,100,45,70,105,30,90,75]
[50, 40, 20, 60, 80, 100, 45, 70, 105, 30, 90,
75][50,40,20,60,80,100,45,70,105,30,90,75]
1. First Partition: Pivot = 75.
Rearrange elements:
o Left: [50,40,20,60,45,70,30][50, 40,
20, 60, 45, 70, 30]
[50,40,20,60,45,70,30]
o Pivot = 75
o Right: [80,100,105,90][80, 100, 105,
90][80,100,105,90]
2. Recursively sort left and right parts.
Time Complexity:
Best/Average Case: O(nlogn)O(n \log
n)O(nlogn), when partitions are
balanced.
Worst Case: O(n2)O(n^2)O(n2), when
partitions are unbalanced (e.g., already
sorted array).
merge_sort(left_half) # Recursively
sort left half
merge_sort(right_half) # Recursively
sort right half
Unit-4
Q1. Explain with example how games can be
formulated using graphs?
Formulating Games using Graphs
Graphs can represent games through their
structure, where nodes represent game
states and edges represent possible moves
or transitions between those states.
Example: Tic-Tac-Toe
1. Game States: Each unique
arrangement of the Tic-Tac-Toe board can
be represented as a node in the graph.
o For instance, the state where X has
moved to the center and O has taken
a corner.
2. Transitions: An edge connects two
nodes if one game state can be reached
from another by a legal move.
o If X moves from the center to a
corner, an edge connects the two
states.
3. Win Conditions: The terminal nodes
(leaf nodes) represent win, lose, or draw
outcomes.
o A node where X has three in a row is
a win state for X.
Game Tree Representation
The game can be represented as a tree
where:
o The root node is the initial state.
o Each level represents a player's turn.
o Branches represent possible moves.
Example Diagram:
scss
Copy code
(Start)
|
+----+----+
| |
X O
(State 1) (State 2)
| |
+--+--+ +--+--+
| | | |
X1 O1 X2 O2
Applications:
Minimax Algorithm: Used to determine
the best move by analyzing game states
and outcomes.
AI Development: AI can explore
possible moves using graphs to make
optimal decisions.
Conclusion:
Graph representation allows for a clear
visualization of game dynamics, making it
easier to analyze and strategize.
elif v != parent[u]:
low[u] = min(low[u], disc[v])
3. Main Function:
python
Copy code
def find_articulation_points(graph):
global time
time = 0
visited = [False] * len(graph)
disc = [float('inf')] * len(graph)
low = [float('inf')] * len(graph)
parent = [None] * len(graph)
ap = [False] * len(graph) # To mark
articulation points
for i in range(len(graph)):
if not visited[i]:
articulation_points(i)
while queue:
# Dequeue a vertex and print it
current = queue.pop(0)
print(current)