通过分析三柱汉诺塔的递归求解过程,我们能够线性递推出移动 n n n个盘子的最小移动次数
设三柱汉诺塔,移动 n n n个盘子的最小移动次数为 T ( 3 , n ) T(3, n) T(3,n)
T ( 3 , n ) = { 1 n = 1 2 f ( 3 , n − 1 ) + 1 n > 1 T(3,n)=\left\{ \begin{aligned} & 1 & n=1 \\ & 2f(3,n-1) +1 & n > 1 \\ \end{aligned} \right. T(3,n)={12f(3,n−1)+1n=1n>1
由此可得 T ( 3 , n ) = 2 n − 1 T(3,n) = 2^n - 1 T(3,n)=2n−1
然而对于多柱汉诺塔问题,我们并没有一个非常直观的策略来移动圆盘。
首先考虑四柱汉诺塔的情况(又称Reve’s Puzzle),对四柱汉诺塔上移动 n n n个盘子,可以通过分成如下 3 3 3个步骤
那么我们的疑问是能够将 1 1 1、 3 3 3两个步骤作为子问题。通过一些简单的运算,我们发现对于较小的 n n n,使用该方法的结果是正确的。
不加证明该递归算法的正确性,我们可以归纳递推式为
T ( 4 , n ) = min 1 ≤ r < n 2 T ( 4 , n − r ) + T ( 3 , r ) T(4, n) = \min_{1 \leq r < n }{2T(4, n-r) + T(3, r)} T(4,n)=1≤r<nmin2T(4,n−r)+T(3,r)
即
T ( 4 , n ) = min 1 ≤ r < n 2 T ( 4 , n − r ) + 2 r − 1 T(4, n) = \min_{1 \leq r < n }{2T(4, n-r) + 2^r - 1} T(4,n)=1≤r<nmin2T(4,n−r)+2r−1
产生的数列
T ( 4 , i ) = A 007664 = 0 , 1 , 3 , 5 , 9 , 13 , 17 , 25 , … T(4, i) = A007664 = 0, 1,3,5,9,13,17,25,\dots T(4,i)=A007664=0,1,3,5,9,13,17,25,…
对该数列进行差分,能够发现产生的数列为
A 137688 = 1 , 2 , 2 , 4 , 4 , 4 , 8 , 8 , 8 , 8 , ⋯ = 2 0 , 2 1 , 2 1 , 2 2 , 2 2 , 2 2 , … A137688 = 1,2,2,4,4,4,8,8,8,8,\dots = 2^0, 2^1, 2^1, 2^2,2^2,2^2,\dots A137688=1,2,2,4,4,4,8,8,8,8,⋯=20,21,21,22,22,22,…
因此我们可以在 O ( n ) O(n) O(n)的时间内计算出 T ( 4 , n ) T(4, n) T(4,n)的结果
对于圆柱的数量 m ≥ 5 m\geq5 m≥5 的情况,我们是否可以继续使用递归的思路?
我们尝试继续使用 3 3 3个步骤描述对 m m m柱汉诺塔的移动方式:
在这种移动过程中,我们会产生一些疑问,如:我们是否可以进行如下操作
这样的话, 1 1 1、 3 3 3两个步骤就难以通过递归方式描述,因为这把 r ’ r’ r’个圆盘放到了两根(甚至更多根)圆柱上
但是我们稍加考虑,假设我们移到 B B B柱上的数量为 r B r_B rB,本质上与我们在之前方案上先移动 r B r_B rB个圆盘,再移动 n − r B n-r_B n−rB个圆盘到 m m m柱上的方案是等价的。
这 3 3 3个步骤已经是Frame-Stewart算法的主要思想,我们在利用公式简要地描述:
T ( m , n ) = min 1 ≤ r < n 2 T ( m , n − r ) + T ( m − 1 , r ) T(m,n) = \min_{1 \le r < n}2T(m,n-r)+T(m-1,r) T(m,n)=1≤r<nmin2T(m,n−r)+T(m−1,r)
对此,除 m = 3 , 4 m=3,4 m=3,4的情况外,我们需要 O ( m n 2 ) O(mn^2) O(mn2)的时间复杂度计算 m m m柱汉诺塔问题,含有 n n n个圆盘时的最少移动次数。