What is a “specification” in the context of algorithm design?
A specification is a pair consisting of a precondition (the requirements for the input data) and a postcondition (the requirements for the output data). It formally defines what the algorithm is expected to do.
What does “correct input data” mean?
Correct input data is data that satisfies the precondition of the algorithm’s specification.
Define “Total Correctness” of an algorithm.
An algorithm is totally correct with respect to a specification if, for any input data that satisfies the precondition, the algorithm eventually stops (terminates) and the resulting output satisfies the postcondition.
Define “Partial Correctness” of an algorithm.
An algorithm is partially correct if, for any input data satisfying the precondition, if the algorithm stops, then the output satisfies the postcondition. It does not guarantee that the algorithm will actually stop.
What is the “Stop Property” (Termination)?
The stop property is the guarantee that for any input satisfying the precondition, the algorithm will reach a final state in a finite number of steps.
What is a “Loop Invariant”?
A loop invariant is a logical formula (condition) that is true before entering the loop and remains true after each iteration of the loop body.
What are the three steps required to prove a loop’s partial correctness using an invariant?
Initialization (Base): Prove the invariant is true before the first iteration.
Maintenance (Step): Prove that if the invariant is true before an iteration, it remains true after the iteration.
Termination (Stop): Prove that when the loop stops, the invariant combined with the stop condition implies the desired target condition (postcondition).
Provide an example of a loop invariant for an algorithm finding the maximum value in an array.
For an algorithm finding the maximum x in an array Arr of length len, an appropriate invariant is: ∀ 0 ≤ j < i : x ≥ Arr[j] ∧ ∃ 0 ≤ j < len : x == Arr[j]. This states that x is the maximum of the elements seen so far (up to index i) and that x is indeed one of the elements from the array.
How do you conclude the proof of correctness for the maximum-finding algorithm when the loop finishes?
When the loop terminates, the stop condition is i == len. By combining this with the invariant (which is still true), we get ∀ 0 ≤ j < len : x ≥ Arr[j], which is exactly the target postcondition.
How is the “Maintenance” step typically proven in a loop?
Maintenance is proven by assuming the invariant holds at the start of an arbitrary iteration and showing that the operations performed inside the loop body (e.g., an if statement that updates a maximum value and an i++ increment) preserve the truth of the formula for the next value of the counter i.
What is the relationship between Total Correctness, Partial Correctness, and the Stop Property?
Total Correctness is equivalent to Partial Correctness plus the Stop Property.
Q1. What are the two obvious conditions that any good algorithm should satisfy?
A good algorithm must first compute the correct or desired output for the given problem. Second, it must be effective, meaning it is “fast” in its execution.
Q2. What does the “complexity” of an algorithm measure?
Complexity measures the efficiency of an algorithm in terms of two basic resources: time and memory. Time complexity measures how fast the algorithm is, while space complexity measures the amount of memory it uses.
Q3. What two things must be determined before starting to assess the time complexity of an algorithm?
Before assessment, one must identify the dominating operation and the data size (typically denoted as $n$ or $len$).
Q4. Define “Dominating Operation.”
A dominating operation is an operation in the algorithm’s code whose total number of executions is proportional to the total number of all operations executed. In searching and sorting, this is usually a comparison between two elements.II. Types of Complexity Functions
Q5. Define “Pessimistic (Worst-case) Time Complexity.”
Pessimistic time complexity, denoted as $W(n)$, is the maximum amount of work (number of dominating operations) an algorithm must perform for any input of a fixed size $n$.
Q6. Define “Average Time Complexity.”
Average time complexity, denoted as $A(n)$, is the expected amount of work performed by the algorithm for an input of size $n$, assuming a specific probability distribution of the input data.
Q7. What is the purpose of asymptotic notation (e.g., Big O, Big Theta)?
Asymptotic notation is used to describe the rank of order of the complexity function. It simplifies the analysis by ignoring constant factors and lower-order terms, focusing on how the resource requirements grow as the input size $n$ increases toward infinity.III. Asymptotic Ranks and Practical Implications
Q8. List the most common ranks of functions in order of increasing complexity.
Constant: $\Theta(1)$Logarithmic: $\Theta(\log n)$Linear: $\Theta(n)$Linear-logarithmic: $\Theta(n \log n)$Square: $\Theta(n^2)$Cubic: $\Theta(n^3)$Sub-exponential: $\Theta(n^{\log n})$Exponential: $\Theta(2^n)$Factorial: $\Theta(n!)$
Q9. What is considered “unacceptably high” complexity in practice?
In practice, an over-polynomial rank of time complexity (such as exponential or factorial) is considered unacceptably high. For space complexity, even a linear rank ($\Theta(n)$) can be considered very high in certain contexts.IV. Case Study: The Search Problem
Q10. How is the time complexity of the “Search Problem” (finding a key in an array) assessed?
Q1. What is the formal specification for the “Searching Problem”?
Input: A sequence of integers $S$ (indexed from 0 to $len-1$) and an integer key to be found.Output: A natural number index less than $len$ such that $S[index] == key$, or -1 if the key is not present in the sequence.
Q2. What is the “Divide and Conquer” rule in algorithm design?
It is a method where a problem is divided into smaller sub-problems such that it is easy to reconstruct the total solution from the sub-solutions. It is often implemented using recursion.
Q3. Why is Sequential Search considered to have optimal time complexity for an unordered sequence?
Sequential search has linear time complexity $W(len) = \Theta(len)$ with a multiplicative factor of 1. It cannot be improved for unordered data because every element might potentially be the key, and no information about the position is available without checking.II. Searching in Sorted Sequences