Our 3D CAD supplier models have been moved to 3Dfindit.com, the new visual search engine for 3D CAD, CAE & BIM models.
You can log in there with your existing account of this site.
The content remains free of charge.
Licensed under Creative Commons Attribution-Share Alike 3.0 (Unkown).
汉诺塔(港台:河內塔)是根据一个传说形成的數學问题:
有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。
问:如何移?最少要移动多少次?
傳說印度某間寺院有三根柱子,上串64个金盤。寺院裡的僧侶依照一個古老的預言,以上述規則移動這些盤子;預言說當這些盤子移動完毕,世界就會滅亡。這個傳說叫做梵天寺之塔問題(Tower of Brahma puzzle)。但不知道是盧卡斯自創的這個傳說,還是他受他人啟發。
若傳說屬實,僧侶們需要264 − 1步才能完成這個任務;若他們每秒可完成一個盤子的移動,就需要5845億年才能完成。整個宇宙現在也不過137億年。
這個傳說有若干變體:寺院換成修道院、僧侶換成修士等等。寺院的地點眾說紛紜,其中一說是位于越南的河內,所以被命名為「河內塔」。另外亦有「金盤是創世時所造」、「僧侶們每天移動一盤」之類的背景設定。
佛教中確實有「浮屠」(塔)這種建築;有些浮屠亦遵守上述規則而建。「河內塔」一名可能是由中南半島在殖民時期傳入歐洲的。
如取N=64,最少需移动264-1次。即如果一秒钟能移动一块圆盘,仍将需5845.54亿年。目前按照宇宙大爆炸理论的推测,宇宙的年龄仅为137亿年。
在真实玩具中,一般N=8;最少需移动255次。如果N=10,最少需移动1023次。如果N=15,最少需移动32767次;这就是说,如果一个人从3岁到99岁,每天移动一块圆盘,他最多仅能移动15块。如果N=20,最少需移动1048575次,即超过了一百万次。
解法的基本思想是递归。假设有A、B、C三个塔,A塔有N块盘,目标是把这些盘全部移到C塔。那么先把A塔顶部的N-1块盘移动到B塔,再把A塔剩下的大盘移到C,最后把B塔的N-1块盘移到C。
每次移动多于一块盘时,则再次使用上述算法来移动。
以 C++ 语言实现:
/*
* Project : hanoi
* File : main.cpp
* Author : iCoding
*
* Date & Time : Sat Oct 06 21:01:55 2012
*
*/
using namespace std;
#include <iostream>
#include <cstdio>
void hannoi (int n, char from, char buffer, char to)
{
if (n == 1)
{
cout << "Move disk " << n << " from " << from << " to " << to << endl;
}
else
{
hannoi (n-1, from, to, buffer);
cout << "Move disk " << n << " from " << from << " to " << to << endl;
hannoi (n-1, buffer, from, to);
}
}
int main()
{
int n;
cin >> n;
hannoi (n, 'A', 'B', 'C');
return 0;
}
// end
// iCoding@CodeLab
//
以 Python 语言实现:
def hanoi(n, a='A', b='B', c='C'):
if n == 1:
print('move', a, '-->', c)
return
hanoi(n-1, a, c, b)
print('move', a, '-->', c)
hanoi(n-1, b, a, c)
print(hanoi(5))
以 Erlang 语言求解:
-module(hanoi).
-export([hanoi/1]).
hanoi(N) when N>0 ->
do_hanoi({N, 1, 3}).
do_hanoi({0, _, _}) ->
done;
do_hanoi({1, From, To}) ->
io:format("From ~p, To ~p~n", [From, To]);
do_hanoi({N, From, To}) ->
do_hanoi({N-1, From, by(From, To)}),
do_hanoi({1, From, To}),
do_hanoi({N-1, by(From, To), To}).
by(From, To) ->
[Result|_] = [1, 2, 3] -- [From, To],
Result.
為了從任意初始結構中找尋最佳解(optimal solution),其演算法可以一般化(be generalized)如下:
以 Scheme 語言表示:
; Let conf be a list of the positions of the disks in order of increasing size.
; Let the pegs be identified by the numbers 0, 1 and 2.
(define (hanoi conf t)
(let ((c (list->vector conf)))
(define (move h f t)
(vector-set! c h t)
(printf "move disk ~s from peg ~s to peg ~s~n" h f t))
(define (third-peg f t) (- 3 f t))
(define (hanoi h t)
(if (> h 0)
(let ((h (sub1 h)))
(let ((f (vector-ref c h)))
(if (not (= f t))
(let ((r (third-peg f t)))
(hanoi h r)
(move h f t)))
(hanoi h t)))))
(hanoi (vector-length c) t)))
在 C語言中:
int conf[HEIGHT]; /* Element conf[d] gives the current position of disk d. */
void move(int d, int t) {
/* move disk d to peg t */
conf[d] = t;
}
void hanoi(int h, int t) {
if (h > 0) {
int f = conf[h-1];
if (f != t) {
int r = 3 - f - t ;
hanoi(h-1, r);
move(h-1, t);
}
hanoi(h-1, t);
}
}
在PASCAL語言中:
procedure Hanoi(n: integer; from, to, by: char);
Begin
if (n=1) then
writeln('Move the plate ',n,' from ', from, ' to ', to)
else begin
Hanoi(n-1, from, by, to);
Writeln('Move the plate ',n,' from ', from, ' to ', to);
Hanoi(n-1, by, to, from);
end;
End;
SAS Institute Inc. 员工 Yinliang Wu 在研究汉诺塔结果数据时发现了一种基于如下隐藏模式的新求解方法:
举例来说:
这种非递归的方式是利用数据统计发现的隐藏模式,可以在著名统计分析语言 SAS 的数据步中轻松实现,也能在其他计算机编程语言中快速实现。
Frame-Stewart演算法本質上也是递归的,可簡單敘述如下:
2011年電影《猿人爭霸戰:猩凶革命》曾出現河內塔以測試猩猩的智商。其后续电影《猩球崛起2》中也有类似的场景。
维基共享资源中相关的多媒体资源:汉诺塔 |
This article uses material from the Wikipedia article "汉诺塔", which is released under the Creative Commons Attribution-Share-Alike License 3.0. There is a list of all authors in Wikipedia
3d,model,playground,board games,computer,strategy,thinktank