Daa Mid 2
Daa Mid 2
To demonstrate that the computing time of the Optimal Binary Search Tree (OBST)
algorithm is O(n³), we analyze the dynamic programming approach used in the
algorithm. The OBST algorithm constructs a binary search tree with the minimum
expected search cost given the probabilities of searching for each key.
1. Input:
o A probability array p[i]p[i]p[i] for the keys and q[i]q[i]q[i] for dummy keys.
2. Goal:
3. Recurrence Relation: The cost C[i,j]C[i, j]C[i,j] of the OBST is given by:
o Compute w[i,j]w[i, j]w[i,j] for all i≤ji \leq ji≤j in O(n2)O(n^2)O(n2) time.
o Solve C[i,j]C[i, j]C[i,j] for all pairs (i,j)(i, j)(i,j) by iterating over all possible
roots r∈[i,j]r \in [i, j]r∈[i,j].
o There are O(n2)O(n^2)O(n2) such pairs of (i,j)(i, j)(i,j) and summing takes
O(1)O(1)O(1) time (due to prefix sums).
o For each pair (i,j)(i, j)(i,j), the algorithm iterates over all possible roots
r∈[i,j]r \in [i, j]r∈[i,j], which takes O(n)O(n)O(n) time.
Conclusion:
The time complexity of the OBST algorithm is O(n3)O(n^3)O(n3). This is due to the
nested loops:
2. One inner loop to iterate over all roots r∈[i,j]r \in [i, j]r∈[i,j] (O(n)O(n)O(n)).
Using a dynamic programming approach coupled with the set generation approach, show how
to obtain an 0(2n/2) algorithm for the 0/1 knapsack problem.
Problem Statement
Given:
Objective:
Maximize the total value of items in the knapsack such that the total weight
does not exceed WWW.
Meet-in-the-Middle Algorithm
2. Generate Subsets:
o Similarly, for Group 2, generate all subsets and store them in a list
L2L_2L2.
4. Combine Results:
o For each pair (w1,v1)∈L1(w_1, v_1) \in L_1(w1,v1)∈L1, find the best
match (w2,v2)∈L2(w_2, v_2) \in L_2(w2,v2)∈L2 such that: w1+w2≤Ww_1
+ w_2 \leq Ww1+w2≤W
o Iterate over all valid combinations of subsets from L1L_1L1 and L2L_2L2
and find the combination with the maximum total value.
Time Complexity
1. Subset Generation:
2. Pruning (Sorting):
3. Combining Results:
Total Complexity:
O(2n/2)O(2^{n/2})O(2n/2)
Example
1. Divide Items:
2. Generate Subsets:
3. Prune Lists:
4. Combine Results:
o Match subsets from L1L_1L1 and L2L_2L2 to maximize the value while
keeping weight≤Wweight \leq Wweight≤W.
This approach is efficient for moderately large nnn and is much faster than the brute-
force O(2n)O(2^n)O(2n) approach for the 0/1 Knapsack Problem.
Inputs:
Problem instance.
Outputs:
Steps:
1. Initialization:
o Insert the root node S0S_0S0 into PQPQPQ with its cost f(S0)f(S_0)f(S0).
2. Branching:
4. Evaluate children:
3. Termination:
o g(x)g(x)g(x): Cost from the root node to the current node xxx.
Algorithm LC_Branch_and_Bound(S_0):
if N is an answer node:
if N_i is feasible:
Explanation
1. Priority Queue:
o Ensures the algorithm always explores the node with the least cost next.
2. Branching:
o Each node represents a partial solution, and its children represent further
exploration of that solution space.
3. Pruning:
o Nodes that are infeasible or dominated by better solutions are not added
to PQPQPQ.
4. Heuristic h(x)h(x)h(x):
o The quality of h(x)h(x)h(x) affects the efficiency of the algorithm but not
its correctness.
Complexity
Time Complexity: Depends on the branching factor bbb and the depth ddd of
the solution.
Problem:
Using LC Branch and Bound, the algorithm explores the partial tours and finds the
shortest tour satisfying the TSP constraints.
BACKTRACKING ~
Pseudocode
python
Copy code
Backtrack(X):
if X is a solution:
else:
Explanation
Key Components:
1. Input:
2. Base Case:
3. Recursive Exploration:
o For the current state XXX, generate all feasible options (choices).
4. Feasibility Check:
o Before extending XXX with an option, check if the option satisfies the
problem's constraints.
5. Recursive Call:
o If the option is valid, extend XXX and recursively call the backtracking
function to explore further possibilities.
o After exploring one branch, undo the move by removing the option from
XXX.
o This ensures the algorithm can explore other branches of the solution
tree.
Problem:
Place nnn queens on an n×nn \times nn×n chessboard such that no two queens attack
each other.
Pseudocode:
python
Copy code
return
XXX: The current state is represented by the board and the current row.
Base Case: When all rows are filled with valid queen placements, XXX is a
solution.
Characteristics of Backtracking
1. Recursive Nature:
2. Search Tree:
3. Pruning:
4. Reversibility:
Applications
o Sudoku
o N-Queens
o Crossword puzzles
2. Combinatorial Problems:
o Subset generation
o Permutations
o Graph coloring
3. Optimization Problems:
o Knapsack problem
The algorithm ensures that a vertex is assigned the next valid color that satisfies the
graph's constraints.
Inputs:
Output:
The next valid color for the vertex, or None if no color is valid.
Algorithm:
python
Copy code
Helper Function:
python
Copy code
return False
return True
Explanation
1. Color Iteration:
o The algorithm iterates through all possible colors from 111 to MMM.
2. Validity Check:
o For each color, it checks if the color can be assigned to the current vertex
without violating the coloring constraints:
3. Return Value:
Problem Statement:
Given:
Pseudocode:
python
Copy code
n = len(S)
return
return
subset.append(S[index])
subset.pop()
Backtrack(0, 0, [])
return result
Explanation:
1. Input Parameters:
o Arguments:
o Base Cases:
o Recursive Calls:
3. Result:
o The result list contains all subsets whose sum equals TTT.
Example
Input:
python
Copy code
S = [3, 5, 6, 7]
T = 10
Execution:
python
Copy code
result = SubsetSum(S, T)
print(result)
Output:
python
Copy code
Time Complexity:
1. Subset Generation:
2. Pruning:
o The algorithm prunes branches when current_sum > T.
3. Overall Complexity:
Space Complexity:
The maximum depth of the recursion is O(n)O(n)O(n) (due to the subset stack).
This algorithm is a clear and efficient recursive solution to the Sum of Subsets
Problem, utilizing backtracking to explore and prune the solution space.
A Hamiltonian cycle is a cycle in a graph that visits each vertex exactly once and
returns to the starting vertex. Finding a Hamiltonian cycle can be done using
backtracking.
Inputs:
Outputs:
Pseudocode:
python
Copy code
def HamiltonianCycle(Graph):
return False
return True
def Backtrack(pos):
for v in range(1, n): # Try all vertices except the starting vertex
if IsSafe(v, pos):
path[pos] = v
if Backtrack(pos + 1):
return True
return False
if Backtrack(1):
return path
else:
Steps:
1. Path Initialization:
o Start the cycle at vertex 0 and initialize all other positions in the path as -
1.
2. Recursive Backtracking:
o If all vertices are included in the path, check if the last vertex connects
back to the starting vertex to complete the cycle.
4. Backtracking:
o If no valid vertex can be added, remove the last vertex (backtrack) and
try the next possibility.
5. Output:
Example
Input:
python
Copy code
Graph = [
[0, 1, 1, 1],
[1, 0, 1, 0],
[1, 1, 0, 1],
[1, 0, 1, 0]
Execution:
python
Copy code
result = HamiltonianCycle(Graph)
print(result)
Output:
csharp
Copy code
o For each vertex, it tries n−1n-1n−1 possible choices in the worst case.
2. Pruning:
o Feasibility checks using IsSafe prune some branches of the recursion tree,
reducing the actual number of calls.
3. Worst-Case Complexity:
4. Space Complexity:
Conclusion
Practical Improvements: