11.24 64阶汉诺塔完成需要5800亿年?手写一个汉诺塔递归算法

汉诺塔是一个非常经典的数学模型,它有一个古老的传说。相传印度主神大梵天在创造世界的同时,也造了三根金刚石柱子。

其中一根柱子上放着64个大小均不相同的圆盘。大梵天命令婆罗门将这64个圆盘按照从大到小的顺序移动到另一根柱子上,在移动的过程中始终要保持大盘在下,小盘子在上。这就是最早关于汉诺塔的古老传说。这其实是一种时间的象征,因为按照这个规则,将64个圆盘移动到另一个圆柱上,在时间上来说几乎是不可能的,需要的时间可能比宇宙诞生的时间还要长,具体为什么?文章会为大家详细说明。

64阶汉诺塔完成需要5800亿年?手写一个汉诺塔递归算法

我们首先将这个游戏简化。

我们设定有A、B、C三根柱子,A柱子上从下往上放的是从大到小依次排好顺序的盘子,B和C柱子是空的。我们需要将A柱子上所有的圆盘移动到C柱子上,移动的过程中,始终保持大盘子在下,下盘子在上,这就是汉诺塔的游戏规则。

64阶汉诺塔完成需要5800亿年?手写一个汉诺塔递归算法

先从最基础的说起。

  • 一个圆盘子:如果只有一个圆盘子,那只需要移动一次,直接移动到C柱子上。
64阶汉诺塔完成需要5800亿年?手写一个汉诺塔递归算法

  • 两个圆盘子
    :如果有两个圆盘子,我们需要借助B柱子,将第一个盘子移动到B柱子上,第二个盘子移动到C柱子上,然后将B柱子上的盘子移动到C柱子上。这样两个盘子就全部移动过来,总共需要3步。
64阶汉诺塔完成需要5800亿年?手写一个汉诺塔递归算法

  • 三个圆盘子:我们给圆盘子依次编号为1、2、3。从规则判断,首先,我们需要将3移动到C柱子的最底部,所以,我们需要将2和1移动到B柱子上。根据前面讲过,我们需要3步就可以了,然后移动3到C。最后重复之前的步骤,将2和1移动到C上。完整的步骤就是1—C,2—B,1—B,3—C,1—A2—C,1—C,总共需要7步完成。
64阶汉诺塔完成需要5800亿年?手写一个汉诺塔递归算法

通过1、2、3阶汉诺塔移动步骤,我们可以推倒出一个公式:

 完成步骤=2^n-1,n代表盘子的个数

通过公式我们可以推倒出,四阶汉诺塔需要15步骤,五阶汉诺塔需要31步骤,而64阶汉诺塔需要多少步骤呢?2的64次方减1(18446744073709500000),需要这么多步骤。假设一个步骤需要1秒,我们将结果换算成年的单位:

 2^64-1=18446744073709500000 
1年=360*24*3600=31104000秒

大概需要5800亿年。宇宙大爆炸至今才45亿年。假设从那时候开始玩,离完成还需要很多很多年,估计玩到人类灭绝还玩不完。

每一个游戏背后都有一个逻辑算法在里面。通过汉诺塔我们已经分析出它的算法,现在我们用Java语言实现它的算法。

64阶汉诺塔完成需要5800亿年?手写一个汉诺塔递归算法

我们通过运行方法可以得到1-5阶汉诺塔步骤:

  • 一阶:路线:A--->C
  • 二阶:路线:A--->B A--->C B--->C
  • 三阶:路线:A--->C A--->B C--->B A--->C B--->A B--->C A--->C
  • 四阶:路线:A--->B A--->C B--->C A--->B C--->A C--->B A--->B A--->C B--->C B--->A C--->A B--->C A--->B A--->C B--->C
  • 五阶:路线:A--->C A--->B C--->B A--->C B--->A B--->C A--->C A--->B C--->B C--->A B--->A C--->B A--->C A--->B C--->B A--->C B--->A B--->C A--->C B--->A C--->B C--->A B--->A B--->C A--->C A--->B C--->B A--->C B--->A B--->C A--->C
  • ...

通过代码我们可以算出任意阶的汉诺塔步骤。64阶的汉诺塔步骤电脑也可以算出来,但是电脑需要跑很长时间,即使算出来,也没有条件存储步骤的数据。

附上一段64阶汉诺塔程序运行的视频

算法的逻辑其实很简单:当level(代表几阶汉诺塔)=1的时候,从第一个塔移动到第三个塔,这是一种特殊情况。当level>1时候,递归移动level-1层汉诺塔,直到leve=1停止递归。

这就是汉诺塔的递归算法,古人的智慧真的是很强大。

64阶汉诺塔完成需要5800亿年?手写一个汉诺塔递归算法


分享到:


相關文章: