Algorithm Analysis and Design Exam 2021
Algorithm Analysis and Design Exam 2021
Kruskal’s Algorithm finds a Minimum Spanning Tree (MST) by sorting all edges in increasing order of weight, then adding edges to the MST, provided adding them does not form a cycle, until all vertices are included. It differs from Prim’s Algorithm, which grows the MST by starting from a single vertex and adding the cheapest edge from the growing MST to a vertex not yet in it. Kruskal's approach focuses on edges and their weights globally, while Prim's expands the tree from a specific node locally .
Understanding the concept of NP-completeness is crucial in computational complexity theory because it helps identify problems for which no efficient solution algorithm is known. NP-complete problems are significant as they lie at the intersection of NP problems, wherein it is hard to find solutions but easy to verify them. If any NP-complete problem can be solved in polynomial time, then all problems in NP can be solved efficiently. Thus, NP-completeness highlights the boundary between feasible and infeasible computations, guiding research and resource allocation .
Dynamic programming solves problems by breaking them down into overlapping subproblems, solving each subproblem once, and storing their solutions. It is used for optimization problems where solutions to subproblems can be reused. Greedy algorithms, on the other hand, build up a solution piece by piece, always choosing the next piece that offers the most immediate benefit. While greedy algorithms are generally faster, they do not always provide an optimal solution, whereas dynamic programming does, although at usually higher computational cost .
The analysis of algorithms is crucial because it helps determine their efficiency by analyzing the time and space they consume. It contributes to understanding their efficiency through worst-case, best-case, and average-case complexity. The worst-case complexity provides the maximum time needed, best-case gives the minimum, and average-case offers an expectation of the time for typical inputs. Analyzing these scenarios allows developers to predict the algorithm's performance, optimize resource usage, and make informed decisions when choosing algorithms .
The principle of optimality in dynamic programming states that an optimal solution to any problem consists of optimal solutions to its subproblems. This means breaking down a problem into smaller, more manageable parts that can be solved individually and combined. An example is the 0/1 Knapsack Problem, where the optimal solution for a knapsack of given capacity is built from optimal solutions of smaller capacities. By using dynamic programming, one can store solutions to subproblems and use them to build up solutions to larger ones, thus ensuring efficiency and optimality .
Backtracking is a recursive, depth-first search technique for solving computational problems, where solutions are incrementally built, abandoned when a conflict arises, and systematically tried in different configurations. In the N-Queens Problem, backtracking involves placing queens one by one in different columns, reverting if a placement leads to a conflict, and trying the next possibility. For a 4-Queens configuration, a queen is placed in the first row, and the algorithm moves to the next row, checking safe positions, and backtracks when necessary until all queens are placed safely without threats .
The key characteristics of an algorithm include definiteness, which ensures that each step is precisely stated; input, as an algorithm must take at least zero or more inputs; output, resulting in one or more results; finiteness, ensuring the algorithm has an end; and effectiveness, meaning that all operations are basic enough to be performed in a finite amount of time. These characteristics are significant because they ensure that the algorithm can perform tasks accurately and efficiently, making it a reliable solution in computer science problems .
A Huffman code is constructed by creating a binary tree where each leaf represents a character from the set, and the path from the root to a leaf corresponds to the binary code for that character. Nodes are created by merging the two least frequent nodes, repeating this until one node remains. For the frequencies given (A: 50, b: 20, c: 15, d: 30), nodes are merged starting with the smallest frequencies. This results in prefix-free codes that map more frequent characters to shorter codes, making the Huffman code optimal for data compression by reducing the total bit count needed for storage .
Understanding spurious hits in the Rabin-Karp algorithm is important because they can lead to false positive matches, affecting the algorithm’s efficiency. Spurious hits occur when substrings have identical hash values but do not match. By checking the actual content of the substrings when hash values match, these spurious hits can be determined and eliminated. This allows the algorithm to efficiently find occurrences of a pattern within a text without unnecessary computations on incorrect substrings .
The LCS problem can be solved using dynamic programming by constructing a matrix that represents all possible pairs of prefixes of the two strings. Through this matrix, subproblems are solved and combined to build up to the solution for the entire strings. For the strings A = 'acabaca' and B = 'bacac', the dynamic programming method involves filling the matrix such that the value at each cell represents the length of the LCS of the prefixes. The filled matrix can then be traced back from the bottom-right to determine the LCS, which is 'bcac' in this case .