Sei sulla pagina 1di 32

Legend has it that there were three diamond needles set into the floor of the temple of Brahma

in Hanoi.

Stacked upon the leftmost needle were 64 golden disks, each a different size, stacked in concentric order:

The priests were to transfer the disks from the first needle to the second needle, using the third as necessary.

But they could only move one disk at a time, and could never put a larger disk on top of a smaller one.
When they completed this task, the world would end!

For simplicity, suppose there were just 3 disks, and well refer to the three needles as A, B, and C...

Since we can only move one disk at a time, we move the top disk from A to B.

For simplicity, suppose there were just 3 disks, and well refer to the three needles as A, B, and C...

We then move the top disk from A to C.

For simplicity, suppose there were just 3 disks, and well refer to the three needles as A, B, and C...

We then move the top disk from B to C.

For simplicity, suppose there were just 3 disks, and well refer to the three needles as A, B, and C...

We then move the top disk from A to B.

For simplicity, suppose there were just 3 disks, and well refer to the three needles as A, B, and C...

We then move the top disk from C to A.

For simplicity, suppose there were just 3 disks, and well refer to the three needles as A, B, and C...

We then move the top disk from C to B.

For simplicity, suppose there were just 3 disks, and well refer to the three needles as A, B, and C...

We then move the top disk from A to B.

For simplicity, suppose there were just 3 disks, and well refer to the three needles as A, B, and C...

and were done!


The problem gets more difficult as the number of disks increases...

Todays problem is to write a program that generates the instructions for the priests to follow in moving the disks.

While quite difficult to solve iteratively, this problem has a simple and elegant recursive solution.

For flexibility, lets allow the user to enter the number of disks for which they wish a set of instructions:
/* hanoi.cpp * ... */ void Move(int n, char src, char dest, char aux); int main() { cout << \n\nThe Hanoi Towers!\n\n << Enter how many disks: ; int numDisks; cin >> numDisks; } Move(numDisks, A, B, C);

Our task, then is to write function Move() that does all the work:
/* hanoi.c * ... */ void Move(int n, char src, char dest, char aux); int main() { int numDisks; printf(\n\nThe Hanoi Towers!\n\n); printf(Enter how many disks: ); scanf(%d,&numDisks);

Move(numDisks, A, B, C);

Basis: What is an instance of the problem that is trivial? n == 1

Since this base case could occur when the disk is on any needle, we simply output the instruction to move the top disk from src to dest.

Basis: What is an instance of the problem that is trivial? n == 1

Since this base case could occur when the disk is on any needle, we simply output the instruction to move the top disk from src to dest.

Induction Step: n > 1 How can recursion help us out?

a. Recursively move n-1 disks from src to aux.

Induction Step: n > 1 How can recursion help us out?

b. Move the one remaining disk from src to dest.

Induction Step: n > 1 How can recursion help us out?

c. Recursively move n-1 disks from aux to dest...

Induction Step: n > 1 How can recursion help us out?

d. Were done!

We can combine these steps into the following algorithm: 0. Receive n, src, dest, aux. 1. If n > 1: a. Move(n-1, src, aux, dest); b. Move(1, src, dest, aux); c. Move(n-1, aux, dest, src); Else Display Move the top disk from src to dest. End if.

// ...

void Move(int n, char src, char dest, char aux) { if (n > 1) { Move(n-1, src, aux, dest); Move(1, src, dest, aux); Move(n-1, aux, dest, src); } else printf(Move the top disk from %c to%c\n,src,dest); }

The Hanoi Towers Enter how many disks: 1 Move the top disk from A to B

The Hanoi Towers Enter how many disks: 2 Move the top disk from A to C Move the top disk from A to B Move the top disk from C to B

The Hanoi Towers Enter how many disks: 3 Move the top disk from A Move the top disk from A Move the top disk from B Move the top disk from A Move the top disk from C Move the top disk from C Move the top disk from A to to to to to to to B C C B A B B

The Hanoi Towers Enter how many disks: 4 move a disk from needle move a disk from needle move a disk from needle move a disk from needle move a disk from needle move a disk from needle move a disk from needle move a disk from needle move a disk from needle move a disk from needle move a disk from needle move a disk from needle move a disk from needle move a disk from needle A C A B B A A C C B C A A C to to to to to to to to to to to to to to needle needle needle needle needle needle needle needle needle needle needle needle needle needle B B C A C C B B A A B C B B

From the moves necessary to transfer one, two, and three disks, we can find a recursive pattern - a pattern that uses information from one step to find the next step. Unfortunately, if we want to know how many moves it will take to transfer 64 disks from post A to post C, we will first have to find the moves it takes to transfer 63 disks, 62 disks, and so on. Therefore the recursive pattern will not be much help in finding the number of moves or the time it would take to transfer all the disks.

However, the recursive pattern can help us generate more numbers to find an explicit (non-recursive) pattern. Here's how to find the number of moves needed to transfer larger numbers of disks from post A to post C, when M = the number of moves needed to transfer n-1 disks from post A to post C: for 1 disk it takes 1 move to transfer 1 disk from post A to post C; for 2 disks, it will take 3 moves: 2M + 1 = 2(1) + 1 = 3 for 3 disks, it will take 7 moves: 2M + 1 = 2(3) + 1 = 7 for 4 disks, it will take 15 moves: 2M + 1 = 2(7) + 1 = 15 for 5 disks, it will take 31 moves: 2M + 1 = 2(15) + 1 = 31 for 6 disks... ?

Number of Disks 1 2 3 4 5 6

Number of Moves 1 3 7 15 31 63

Number of Disks (n) 1 2 3 4 5 6

Number of Moves 21 - 1 = 2 - 1 = 1 22 - 1 = 4 - 1 = 3 23 - 1 = 8 -1 = 7 24 - 1 = 16 - 1 = 15 25 - 1 = 32 - 1 = 31 26 - 1 = 64 - 1 = 63

So the formula for finding the number of steps it takes to transfer n disks from post A to post C is:

2 n- 1
The number of separate transfers of single disks the priests must make to transfer the tower is 2 to the 64th minus 1, or 18,446,744,073,709,551,615 moves! If the priests worked day and night, making one move every second it would take slightly more than 580 billion years to accomplish the job! - far, far longer than some scientists estimate the solar system will last.

Recursion is a valuable tool that allows some problems to be solved in an elegant and efficient manner. Functions can sometimes require more than one recursive call in order to accomplish their task. There are problems for which we can design a solution, but the nature of the problem makes solving it effectively uncomputable.

Potrebbero piacerti anche