第二章 算法效率分析基础 page 55 汉诺塔问题

汉诺塔问题介绍:
       在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片,一次只移动一片,不管在哪根针上,小片必在大片上面。当所有的金片都从梵天穿好的那根针上移到另外一概针上时,世界就将在一声霹雳中消灭,梵塔、庙宇和众生都将同归于尽。

        这个问题有一个优雅的递归解法,图2.4 描述了这个解法。为了把n > 1个盘子从木桩 1 移到木桩 3(借助木桩2),我们需要先把 n -1 个盘子递归地从木桩 1 移到木桩 2(借助木桩 3),然后直接把最大的盘子(第n个盘子)从木桩 1 移到木桩 3 ,并且,最后把n -1个盘子递归地从木桩 2 移到木桩 3(借助木桩 1 )。当然,如果n= 1,我们可以简单地把这个单独的盘子直接从一个木桩移到另一个木桩。

让我们把前面的一般性方案应用到汉诺塔问题上去。显然,我们可以选择盘子的数量n作为输入规模的一个指标,盘子的移动也可以作为该算法的基本操作。可以清楚地看到,移动的次数M(n)只依赖于n,因此,对于M(n)有下列递推等式:

                                                   当n> 1时,

                                                   M(n) = M (n -1) +I+ M (n -1)

另一个很明显的事实是初始条件M (1) = 1,因此,对于移动次数M(n)我们建立了下面的递推关系:

                                                   当n> 1时,

                                                   M(n)= 2M(n-l)+ 1

                                                   M (1) = 1

我们还是使用反向替换法来解这个递推式:

M(n) = 2M(n-1)+ 1                                                                                替换M(n-1)=2M(n-2)+1

        = 2[2M (n -2) +1]+1 = 2^{2} M (n -2) + 2 + 1                                替换M(n-2) = 2M (n -3) + 1

        = 2^{2}[M (n -3) +1]+ 2 +1= 2^{3} M (n -3) + 2^{2} + 2 + 1

左边前 3 个求和算式的模式预示着下一个算式将是:2^{4}M(n-4)+2^{3}+2^{2} +2+1,对这个模式进行一般化处理,在做了 i 次替换以后,得到下式:

M(n)=2^{i}M(n-i)+2^{i-1}+2^{i-2}+...+2+1=2^{i}M(n-i)+2^{i}-1

因为初始条件是在 n = 1 的情况下确立的,所以必须让 i = n - 1,我们有下列方程来解递推式(2.3):

M(n)=2^{n-1} M (n -(n -1)) + 2^{n-1}+1

M(n)=2^{n-1} M (1)+2^{n-1}-1=2^{n-1}+2^{n-1}-1=2^{n}-1

这样得到了一个指数级的算法,即使 n 的值不算大,该算法的运行时间也会长得无法想像。这并不是因为这个算法不好。不难证明,对于这个问题来说, 这是可能提供的最高效的算法。事实上,是这个问题本身决定了它在计算上的难度。尽管如此,这个例子还是揭示了一个具有普遍意义的重要观点:

我们应该谨慎使用递归算法,因为它们的简洁可能会掩盖它们的低效率.

如果一个递归算法会不止一次地调用它本身,出于分析的目的,构造一棵它的递归调用树是很有用的。在这棵树中,节点相当于递归调用,我们可以用调用参数的值(或者是几个参数的值)作为节点的标记。对于汉诺塔这个例子来说,它的递归调用树在图2.5中给出。 通过计算树中的节点数,我们可以得到汉诺塔算法所做调用的全部次数:

C(n)=2^{n}-1

这个数字就像我们预测的那样,和我们早先求得的移动次数是一致的。
 

那么好多人会问64个圆盘移动到底会花多少时间?那么古代印度距离现在已经很远,这64个圆盘还没移动完么?我们来通过计算来看看要完成这个任务到底要多少时间? 

我们使用通项式:C(n)=2^{n}-1 。当N=64时时 C(64)=18446744073709551615。 

我们假设移动一次圆盘为一秒,那么一年为31536000秒。那么18446744073709551615/31536000约等于584942417355天,换算成年为5845.54亿年。 

目前太阳寿命约为50亿年,太阳的完整寿命大约100亿年。所以我们整个人类文明都等不到移动完整圆盘的那一天。

结论:汉诺塔问题通式如下

C(n)=2^{n}-1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值