算法设计与分析3 - 动态规划解决四柱汉诺塔问题

三、四柱汉诺塔问题
3 、四塔问题:设有 A B C D 四个柱子 ( 有时称塔 ) ,在 A 柱上有由小到大堆放的 n 个盘子,如图所示。

今将 A 柱上的盘子移动到 D 柱上去。可以利用 B C 柱作为工作栈用,移动的规则如下 :
每次只能移动一个盘子。
在移动的过程中,小盘子只能放到大盘子的上面。
设计并实现一个求解四塔问题的动态规划算法,并分析时间和空间复杂性。
 
  算法思想:
用如下算法移动盘子(记为FourPegsHanoi):
1) 、将A柱上n个盘子划分为上下两部分,下方部分共有k(1kn)个盘子,上方部分共有n - k个盘子。
2) 、将A柱上面部分n�Ck个盘子使用FourPegsHanoi算法经过CD柱移至B柱。
3) 、将A柱剩余的k个盘子使用ThreePegsHanoi算法经过C柱移至D柱。
4) 、将B柱上的n�Ck个盘子使用FourPegsHanoi算法经过AC柱移至D柱。
 
ThreePegsHanoi 算法如下(设三个柱子分别为ABCA柱上共有k个盘子):
1) 、将A柱上方k-1个盘子使用ThreePegsHanoi算法经过B柱移至C柱。
2) 、将C柱上最后一个盘子直接移至C盘。
3) 、将B柱上k-1个盘子使用ThreePegsHanoi算法经过A柱移至C柱。
 
 
 
  算法步骤:
根据动态规划的四个步骤,求解如下 :
1) 、最优子结构性质:
   四柱汉诺塔问题的最优解是用最少的移动次数将A柱上的盘子全部移到D柱上。当盘子总数为i时,我们不妨设使用FourPegsHanoi的最少移动次数为f(i)。相应的ThreePegsHanoi 算法移动次数为g(k),由于g(k)=2g(k-1)+1= 2k -1, k确定时,g(k)也是不变的。
   f(i) 为最优解时,其子问题f(i-k)也必为最优解。如果f(i-k)不是最优解,那么存在f(i-k) < f(i-k)。用f(i-k)替换f(i-k)将产生一个比f(i)更优的解。这与f(i)为最优解是矛盾的。所以本问题具有最优子结构性质。
 
2) 、递归地定义问题的最优解:
根据上述FourPegsHanoi算法得到最少移动次数f(i):
3) 、自底向上地计算最优解的值 : ( 相应的 Java 源程序在 Hanoi.java 中。 )
f(i) 对应算法中的 m[i , s[i]]
-----------------------------------------------------------------------------------------
求四柱汉诺塔最小移动次数伪代码:
组下标从 0 开始,数组 m,s 大小为 n+1 数组 m 存储计算最小移动次数的中间值。数组 s 存储每步最小移动次数所对应的分割值 k
MinMovements ( n ):
      m[0,0] ← s[0] ← 0 ▹为了方便计算增加了 f(0) = m[0,s[0]] = 0   
      for i ← 1 to n
           do min ←
                 for k ← 1 to i
                      do m[i , k] ← 2 * m[i �C k , s[i �C k]] + 2k �C 1
                            if m[i , k] < min
                                  then min ← m[i , k]
                                        s[i] = k
      return m[n , s[n]] & s
4) 、根据计算信息构造最优解 :
MinMovements 求出的数组 s 中, s[i] f(i) 所对应的最优分割位置。根据数组 s 来构造移动盘子的最佳序列,伪代码如下 :
-----------------------------------------------------------------------------------------
FourPegsHanoi (i , src, temp1, temp2, dest):
if i = 1
then move(src , dest)
else FourPegsHanoi(i �C s[i] , src , temp2 , dest , temp1)
ThreePegsHanoi(s[i] , src , temp2 , dest)
                  FourPegsHanoi(i �C s[i] , temp1 , src , temp2 , dest)
----------------------------------------------------------------------------------------
ThreePegsHanoi(k , src , temp, dest):
           if k = 1
then move(src , dest)
                 else ThreePegsHanoi(k - 1, src , dest , temp)
                        move(src , dest)
                        ThreePegsHanoi(k - 1, temp , src , dest)
-----------------------------------------------------------------------------------------
   时间空间复杂度分析 :
1 、时间复杂度
MinMovements 算法的时间复杂度为 :
T(n) = 1 + 2 + ... + n = n(n+1)/2 = O(n2)
2 、空间复杂度
MinMovements 算法占用的空间为 m s 数组的大小 :
(n+1)2 + (n+1) = O(n2)
通过分析 m 数组中记录了一些与结果不相关的数据 , 所以通过对 MinMovements 进行改进 , 可使占用空间减小为 O(n)
MinMovements ( n ):
      m[0] ← s[0] ← 0      
      for i ← 1 to n
           do m[i] ←
                 for k ← 1 to i
                      do q ← 2 * m[i �C k] + 2k �C 1
                            if q < m[i]
                                  then m[i] ← q
                                        s[i] ← k
      return m[n] & s

   算法测试
n=10 时,最小移动次数 49 移动序列如下 :
1    A->D
2    A->B
3    A->C
4    B->C
5    D->C
6    A->B
7    A->D
8    B->D
9    A->B
 
10  D->A
11  D->B
12  A->B
13  C->A
14  C->D
15  C->B
16  D->B
17  A->B
18  A->C
19  A->D
 
20  C->D
21  A->C
22  D->A
23  D->C
24  A->C
25  A->D
26  C->D
27  C->A
28  D->A
29  C->D
 
30  A->C
31  A->D
32  C->D
33  B->C
34  B->D
35  B->A
36  D->A
37  C->A
38  B->D
39  B->C
40  D->C
41  B->D
42  C->B
43  C->D
44  B->D
45  A->B
46  A->C
47  A->D
48  C->D
49  B->D
 
n=15 时,最小移动次数 129 。移动序列如下 :
1    A->B
2    A->C
3    A->D
4    C->D
5    B->D
6    A->C
7    A->B
8    C->B
9    A->C
10  B->A
11  B->C
12  A->C
13  D->A
14  D->B
15  D->C
16  B->C
17  A->C
18  A->D
19  A->B
20  D->B
21  A->D
22  B->A
23  B->D
24  A->D
25  A->B
26  D->B
 
27  D->A
28  B->A
29  D->B
30  A->D
31  A->B
32  D->B
33  C->D
34  C->B
35  C->A
36  B->A
37  D->A
38  C->B
39  C->D
40  B->D
41  C->B
42  D->C
43  D->B
44  C->B
45  A->C
46  A->D
47  A->B
48  D->B
49  C->B
50  A->D
51  A->C
52  D->C
 
53  A->D
54  C->A
55  C->D
56  A->D
57  A->C
58  D->C
59  D->A
60  C->A
61  D->C
62  A->D
63  A->C
64  D->C
65  A->D
66  C->A
67  C->D
68  A->D
69  C->A
70  D->C
71  D->A
72  C->A
73  C->D
74  A->D
75  A->C
76  D->C
77  A->D
78  C->A
 
79  C->D
80  A->D
81  B->D
82  B->A
83  B->C
84  A->C
85  D->C
86  B->A
87  B->D
88  A->D
89  B->A
90  D->B
91  D->A
92  B->A
93  C->B
94  C->D
95  C->A
96  D->A
97  B->A
98  B->C
99  B->D
100C->D
101B->C
102D->B
103D->C
104B->C
 
105      B->D
106      C->D
107      C->B
108      D->B
109      C->D
110    B->C
111   B->D
112    C->D
113    A->C
114    A->D
115    A->B
116    D->B
117   C->B
118    A->D
119    A->C
120      D->C
121      A->D
122      C->A
123      C->D
124      A->D
125      B->A
126      B->C
127      B->D
128      C->D
129      A->D

本文出自 “wintysのブログ” 博客,请务必保留此出处http://wintys.blog.51cto.com/425414/100703

你可能感兴趣的:(职场,休闲,算法设计与分析)