四個柱子的漢諾塔


和三個柱子的最初的漢諾塔很類似,只是多了一個柱子,相當於緩存區大了一些,處理的速度自然快了一些。

粗略的C代碼(並沒有使先移動到第四根柱子上面的圓盤的數量是最優):

#include <stdio.h>

int count = 0;

void hanoi (char s, char t1, char t2, char t, int n)
{
    if (0 == n)
        return;
    if (1 == n)
    {
        printf ("%c -> %c\n", s, t);
        printf("%d\n", ++count);
        return;
    }

    hanoi (s, t2, t, t1, n - 2); // 先將 n - 2 個圓盤從 s 移動到 t1
    printf ("%c -> %c\n", s, t2); // 將此時最上面的圓盤移動到 t2 上
    printf("%d\n", ++count);
    printf ("%c -> %c\n", s, t); // 將剩下的最后一個圓盤移動到 t 上
    printf("%d\n", ++count);
    printf ("%c -> %c\n", t2, t); // 將 t2 上的圓盤移動到 t 上
    printf("%d\n", ++count);
    hanoi (t1, s, t2, t, n - 2); // 將 t1 上的圓盤移動到 t上,此時,s 和 t2 成了輔助的柱子

    return;
}

int main ()
{

    hanoi ('A', 'B', 'C', 'D', 8);
    return (0);

}

這個版本就是簡單地先將 n - 2 個圓盤放到第 4 個柱子上,然后將剩下的兩個圓盤轉移到目標柱子上,如此遞歸。所以並不是最優解。

關於對於不同的圓盤的數量,如何控制率先移動到第四個柱子的圓盤的數量,目前只是想到了一種很笨的方法,就是遍歷所有的可能,然后找出最優解,然后存儲到數組中,然后再再遞歸調用移動圓盤的函數的時候進行控制(移動圓盤的函數暫時還沒有實現)。

由於樣本數據取到了64個圓盤,最后的數據會比較大,所以選擇了不限數據大小的Python,進行確定四個柱子的情況下的最少移動的次數和最優的率先移動到第 4 根柱子的圓盤的數量。

Python代碼:

# 最終只在列表中存儲64個數據,第一個數據舍棄,是為了序列能夠從1開始

# 存儲三個柱子的情況,然后初始化
ThreeHanoi = []
ThreeHanoi.append(0)
ThreeHanoi.append(1)
for i in range(2, 65): # 只需要再添加 63 個數據,就湊足了 65 了數據,實際有效的數據只有64個,第一個數據只是為了占位
    ThreeHanoi.append(2 * ThreeHanoi[i - 1] + 1)

# 存儲四個柱子的情況,然后初始化
count4 = 0
FourHanoi = []
FourHanoi.append(0) # 占位
FourHanoi.append(1) # 只有一個圓盤需要移動 1 次
FourHanoi.append(3) # 有兩個圓盤的情況下需要移動 3 次
StoreJ = []
StoreJ.append(0)
StoreJ.append(0)
StoreJ.append(0)
for i in range(3, 65): # 還需要再添加 62 個數據
    min = ThreeHanoi[i]
    flag_j = 0
    for j in range(1, i):
        count4 = 2 * FourHanoi[j] + ThreeHanoi[i - j]
        if count4 < min:
            min = count4
            flag_j = j
    FourHanoi.append(min)
    StoreJ.append(flag_j)

print(ThreeHanoi)
print(FourHanoi)
print(StoreJ)

結果:

[0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647, 4294967295, 8589934591, 17179869183, 34359738367, 68719476735, 137438953471, 274877906943, 549755813887, 1099511627775, 2199023255551, 4398046511103, 8796093022207, 17592186044415, 35184372088831, 70368744177663, 140737488355327, 281474976710655, 562949953421311, 1125899906842623, 2251799813685247, 4503599627370495, 9007199254740991, 18014398509481983, 36028797018963967, 72057594037927935, 144115188075855871, 288230376151711743, 576460752303423487, 1152921504606846975, 2305843009213693951, 4611686018427387903, 9223372036854775807, 18446744073709551615]
[0, 1, 3, 5, 9, 13, 17, 25, 33, 41, 49, 65, 81, 97, 113, 129, 161, 193, 225, 257, 289, 321, 385, 449, 513, 577, 641, 705, 769, 897, 1025, 1153, 1281, 1409, 1537, 1665, 1793, 2049, 2305, 2561, 2817, 3073, 3329, 3585, 3841, 4097, 4609, 5121, 5633, 6145, 6657, 7169, 7681, 8193, 8705, 9217, 10241, 11265, 12289, 13313, 14337, 15361, 16385, 17409, 18433]
[0, 0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 52, 53]

為方便觀察,下面將數據以“盤數 : 最少移動次數,最合適的率先移動的盤數”列出:

1  :  1 ,  0
2  :  3 ,  0
3  :  5 ,  1
4  :  9 ,  1
5  :  13 ,  2
6  :  17 ,  3
7  :  25 ,  3
8  :  33 ,  4
9  :  41 ,  5
10  :  49 ,  6
11  :  65 ,  6
12  :  81 ,  7
13  :  97 ,  8
14  :  113 ,  9
15  :  129 ,  10
16  :  161 ,  10
17  :  193 ,  11
18  :  225 ,  12
19  :  257 ,  13
20  :  289 ,  14
21  :  321 ,  15
22  :  385 ,  15
23  :  449 ,  16
24  :  513 ,  17
25  :  577 ,  18
26  :  641 ,  19
27  :  705 ,  20
28  :  769 ,  21
29  :  897 ,  21
30  :  1025 ,  22
31  :  1153 ,  23
32  :  1281 ,  24
33  :  1409 ,  25
34  :  1537 ,  26
35  :  1665 ,  27
36  :  1793 ,  28
37  :  2049 ,  28
38  :  2305 ,  29
39  :  2561 ,  30
40  :  2817 ,  31
41  :  3073 ,  32
42  :  3329 ,  33
43  :  3585 ,  34
44  :  3841 ,  35
45  :  4097 ,  36
46  :  4609 ,  36
47  :  5121 ,  37
48  :  5633 ,  38
49  :  6145 ,  39
50  :  6657 ,  40
51  :  7169 ,  41
52  :  7681 ,  42
53  :  8193 ,  43
54  :  8705 ,  44
55  :  9217 ,  45
56  :  10241 ,  45
57  :  11265 ,  46
58  :  12289 ,  47
59  :  13313 ,  48
60  :  14337 ,  49
61  :  15361 ,  50
62  :  16385 ,  51
63  :  17409 ,  52
64  :  18433 ,  53

這三行數據依次是三個柱子時的最少移動次數,四個柱子的最少移動次數和四個柱子時率先移動到第四根柱子的最優數量。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM