Learning the basics of algorithmic design and analysis, exercise 2.4 5th asks to design a non-recursive algorithm for Hanoi games.
Think, not the solution. After reading the answer tips:
If you can't, don't be depressed: the non-recursive algorithm of this problem is not complicated, but it is not easy to find. As a consolation, you can find answers on the internet.
Well, the words are so straightforward, so Baidu, get a feeling very good answer, slightly do modify, excerpt in the following:
Original address: http://blog.sina.com.cn/s/blog_48e3f9cd01000474.html
#################################################################################
#################################################################################
In the version of someone to discuss the Hanoi of non-recursive algorithm, someone introduced how non-recursive, I think for a while, finally want to understand. Tidy up the next convenient to everyone: Hanoi Tower problem:
In India, there is an old legend: in the world center of Sheng Miao (in northern India), a yellow copper plate is inserted with three stone needles. In the creation of the world, The Hindu god Brahma, on one of the needles, dressed from the bottom to the top 64 pieces of gold, the so-called Hanoi. No matter the day or night, there is always a monk in accordance with the following rules to move these pieces of gold, one at a time, no matter where the needle, the small pieces must be on top of the large. The world will be wiped out in a thunderbolt when all the gold is moved from the needle on which Brahma is dressed, and the Vatican, the temple and all sentient beings will perish. Recursive algorithm: define void Hanoi (char src, char des, char via, int n)
Indicates that n plates are moved from src to des by means of via.
Obviously there are
void Hanoi (charcharcharint N) { 1); // move the nth plate directly from src to des 1 ); }
Based on the recursive algorithm, set F (n) as the number of times the n plates are to be moved.
So obviously:
F (n + 1) = 2*f (n) + 1 , [F (n + 1) + 1] = * * *[f (n) + 1]
f (1) = 1,-> f (n) + 1 = (1 + 1) ^n, f (n) = 2^n-1
. F (64) = 2^64-1=18446744073709551615
How long will it take to do it every second? About 31,536,926 seconds a year, the calculations show that it takes more than 580 billion years to finish these pieces of gold, longer than the Earth's life, in fact, the world, the Vatican, the temples, and all sentient beings have vanished. Non-recursive algorithm:
Define the plate numbers from small to large, respectively, to 1,2,......N.
You can use a 1 to 2^n-1 2 binary sequence to simulate the sequence of the plates that were moved during the process of the N-plate in the Nottingham Tower. Given an n, we can tell by the 0 to 2^n-1 sequence that the plate should be moved at any one step.
Judging method: The number of plates moved by step m is the position of the lowest bit 1 in binary representation of M. Proof: n = 1, apparently established.
Suppose n = k is established.
n = k + 1 o'clock, corresponds to sequence 1 to 2^ (k+1)-1, obviously this sequence about 2^k symmetrical.
Let's say we're going to move K + 1 plates from A to C.
Then the 2^k can correspond to move (k + 1, A, C). 1 to 2^k-1 according to assumptions can
Corresponds to Hanoi (A, B, C, K). As for 2^k + 1 to 2^ (k + 1)-1 The highest bit 1 is removed from the corresponding sequence into 1 to 2^k-1, apparently 2^k + 1 to 2^ (k + 1)-1 and 1 to 2^k-1 the lowest bit of the corresponding element in the sequence is the same position as 1. So 2^k + 1 to 2^ (k + 1)-1 can correspond to Hanoi (B, C,a,k).
So to n = k + 1 is also established. The following discussion of step m should move the corresponding plate from where to where?
The definition order is a->b->c->a, and reverse is c->b->a->c. The nature of the Hanoi of n plates, any plate K (k <= N) k is either sequential or always reversed during the entire Hanoi movement. And if K moves the order of the process in n plates and k-1 (if k > 1) and K + 1 (if k < n) the order is reversed.
For example: n = 3
1 a->c2 a->b1 c->b3 a->c1 b->A2 b->C1 a->c
Where 1 of the trajectory a->c->b->a>c reverse, 2 of the trajectory a->b->c sequence, 3 of the trajectory a->c reverse order
Proof: Suppose N <= K was established
For n = k + 1 According to the recursive algorithm
Hanoi (a,c,b,k + 1) = Hanoi (A, B, C, K) + Move (A, C, K + 1) + Hanoi (b, c,a,k); the whole process of plate K + 1 moves only once a->c for reverse order corresponds to 2^k. For any plate M < K + 1,
The movement of M plates consists of two parts consisting of the first half Hanoi (A, B, C, K) and the second half of Hanoi (b, C,a,k). It is clear that if M is in Hanoi (A, C, B, K) trajectory sequence, then M is in reverse order in Hanoi (A, B, C, K) and Hanoi (b, C,a,k). Vice versa. These two parts are linked together to prove that M is reversed in Hanoi (A,c,b,k) and Hanoi (A,c,b,k + 1).
At the same time, the largest plate in the Hanoi Tower is always in reverse order and moves only 1 steps, A->c.
In this case: M = k + 1, in Hanoi (A,c,b,k + 1) is reverse order.
m = k, because it is in reverse order in Hanoi (A,c,b,k), so Hanoi (A,c,b,k + 1) is sequential.
m = k-1, because the Hanoi (A,C,B,K-1) is in reverse order, so Hanoi (A,c,b,k) is sequential, so Hanoi (A,c,b,k + 1) is reversed.
Go down in turn ...
The conclusion is to be proven. Summary: in n Nottingham in N, N-2, n-4 ... Is the reverse movement, n-1, n-3,n-5 ... are sequential moves. With these conclusions, non-recursive procedures are well written. A recursive and non-recursive comparison program was written:
#include<iostream>using namespacestd;voidHanoi (CharSrcCharDesCharViaintN) { if(n = =1) {cout<< N <<" : "<< src <<" -"<<des <<Endl; return; } Hanoi (SRC, via, DES, N-1); cout<< N <<" : "<< src <<" -"<<des <<Endl; Hanoi (Via, DES, SRC, n-1);}intMain () {intN; Cin>>N; cout<<"recusive:"<<Endl; Hanoi ('A','C','B', N); cout<<Endl; cout<<"Normal:"<<Endl; Charorder[2][ the]; Charpos[ -]; for(intI=0;i< -; i++) {Pos[i]='A';//At the beginning, all the disc positions are ' A ';} order[0]['A'] ='B'; order[0]['B'] ='C'; order[0]['C'] ='A'; order[1]['A'] ='C'; order[1]['B'] ='A'; order[1]['C'] ='B'; //0 is sequence 1 is reverse order intindex[ -]; //determine the order of the tracks or reverse them intI, J, M; for(i = n; i >0; I-=2) Index[i]=1; for(i = n-1; i >0; I-=2) Index[i]=0; memset (POS,'A',sizeof(POS)); for(i =1; I < (1<< N); i + +) { for(M =1, j = i; j%2==0; J/=2, M + +);//calculates the position of the lowest bit 1 of the current step ordinal. cout << M <<" : "<< Pos[m] <<" -"<< Order[index[m]][pos[m]] <<Endl; POS[M]= Order[index[m]][pos[m]];//Change the current location } return 0;}
Exclamation the original author's algorithm is really subtle.
Additionally: The problem of calculating the lowest bit of an integer bit of 1 can be calculated as follows:
int lowestbit (int n) { int tmp=n-1; TMP// assuming that the minimum bit of n is 1 for M, then TMP is a number with a low m bit of 1 and a remaining high of 0. tmp+=1; // at this time tmp= pow (2,m); return log2 (TMP);}
Algorithm Learning (4)----Hanoi recursive algorithm and non-recursive algorithm