Prev: The Basis Cases Next: Loop Invariants |
What Every CMPT 225 Student Should Know About Mathematical Induction
- by Brad Bart, Simon Fraser University | |
Part 1: Overview of Induction
Part 2: How Induction Relates to Computer Science
|
Part 2: How Induction Relates to Computer Science
Induction is about mathematical structures which are self-similar. So are algorithms and computer programming, both of which apply recursion and iteration to solve problems.
Recursion is an algorithmic technique where you solve a problem by using the solutions to smaller instances of the same problem. The inductive step from the squares example was recursive because in order to verify the nth case, you relied on the n − 1st case. But similarly, case n − 1 depended on case n − 2. And case n − 2 depended on case n − 3, which depended on case n − 4, . . ., which depended on case 3, which depended on case 2, which depended on case 1. And since case 1 was verified in the basis step, you concluded the nth case was true.
This sort of recursive reasoning, where you break down the large case
into smaller cases, is known as the top-down approach.
In this example, it leads directly to a recursive implementation of the
function int SumOdd(int n) { // base case if (n == 1) return 1; // recursive case return SumOdd(n-1) + (2*n - 1); }
The other way to look at induction is by starting with case 1, the basis case. Then, by using the inductive step, case 1 implies case 2. Now that you have case 2, you use the inductive step again, and you have case 3. Case 3 implies case 4, which implies case 5, which implies case 6, and so on, climbing your infinite ladder, rung by rung, going as high as you like.
This sort of recursive reasoning, where you use the smaller cases to
build up to the large case, is known as the bottom-up approach.
In the squares example, it leads directly to an iterative implementation
of the function int SumOdd(int n) { total = 1; for (int i = 2; i <= n; ++i) { // assert(total == (i-1)*(i-1)); total += (2*i - 1); // assert(total == i*i); } }The two assertions in the implementation serve to convince the reader that the code does just what it is supposed to do: that at the beginning of the loop ∑ = (i − 1)2, and at the end of the loop ∑ = i2. An assertion about how the data of the algorithm relate to the loop index is called a loop invariant. | |
Next: Loop Invariants |