修改了河内塔

时间:2014-07-23 11:44:23

标签: algorithm math towers-of-hanoi

我们都知道解决河内问题经典塔所需的最小移动次数是2 n -1。现在,让我们假设一些光盘具有相同的尺寸。在这种情况下解决问题的最小移动次数是多少。

示例,我们假设有三张光盘。在经典问题中,所需的最小移动次数为7.现在,让我们假设盘2和盘3的大小相同。在这种情况下,所需的最小移动次数为:

  1. 将光盘1从a移动到b。
  2. 将光盘2从a移动到c。
  3. 将光盘3从a移动到c。
  4. 将光盘1从b移动到c。
  5. 这是4招。现在,考虑到光盘总数n和具有相同尺寸的光盘组,找到解决问题的最小移动次数。这是朋友的挑战,因此欢迎提出解决方案。谢谢。

3 个答案:

答案 0 :(得分:4)

让我们考虑一个大小为n的塔。顶部磁盘必须移动2 n-1 次,第二个磁盘2 n-2 次,依此类推,直到底部磁盘只需移动一次,共计2次 n -1次移动。移动每个磁盘只需转一圈。

   1      moved 8 times
  111     moved 4 times
 11111    moved 2 times
1111111   moved 1 time   => 8 + 4 + 2 + 1  ==  15

现在,如果 x 磁盘具有相同的大小,那么它们必须位于连续的层中,并且您总是将它们移向相同的目标堆栈,因此您也可以将它们折叠为一个磁盘,要求 x 转动。如果您愿意,可以将这些多磁盘 x 倍视为“重”或“厚”。

   1
  111                       1      moved 8 times
  111       collapse       222     moved 4 times, taking 2 turns each
 11111    ----------->    11111    moved 2 times
1111111                  3333333   moved 1 time, taking 3 turns
1111111                            => 8 + 4*2 + 2 + 1*3  ==  21
1111111

现在只需总结一下,你就得到了答案。

以下是一些Python代码,使用上面的示例:假设您已经有一个“折叠”磁盘列表,其中disks[i]i层中折叠磁盘的权重,可以这样做:

disks = [1, 2, 1, 3]           # weight of collapsed disks, top to bottom
print sum(d * 2**i for i, d in enumerate(reversed(disks)))

如果你有一个磁盘大小列表,比如在左侧,你可以使用这个算法:

disks = [1, 3, 3, 5, 7, 7, 7]  # size of disks, top to bottom
last, t, s = disks[-1], 1, 0
for d in reversed(disks):
    if d < last: t, last = t*2, d
    s = s + t
print s 

在两种情况下,输出都是21,即所需的转弯次数。

答案 1 :(得分:1)

完全取决于相同尺寸的光盘分布。如果您有n = 7张光盘并且它们的大小相同,那么答案是7(或n)。当然,标准问题由2 n -1回答。

正如tobias_k建议的那样,您可以对相同尺寸的光盘进行分组。所以现在将问题视为移动光盘组。要移动一定数量的组,您必须知道每个组的大小

<强>实施例

1

n=7   //disc sizes (1,2,3,3,4,5,5)
g=5   //group sizes (1,1,2,1,2)
      //group index (1,2,3,4,5)

number of moves = sum( g-size * 2^( g-count - g-index ) )

in this case
moves = 1*2^4 + 1*2^3 + 2*2^2 + 1*2^1 + 2*2^0
      = 16 + 8 + 8 + 2 + 2
      = 36

2

n=7   //disc sizes (1,1,1,1,1,1,1)
g=1   //group sizes (7)
      //group index (1)

number of moves = sum( g-size * 2^( g-count - g-index ) )

in this case
moves = 7*2^0
      = 7

3

n=7   //disc sizes (1,2,3,4,5,6,7)
g=7   //group sizes (1,1,1,1,1,1,1)
      //group index (1,2,3,4,5,6,7)

number of moves = sum( g-size * 2^( g-count - g-index ) )

in this case
moves = 1*2^6 + 1*2^5 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0
      = 64 + 32 + 16 + 8 + 4 + 2 + 1
      = 127

有关最后一个例子和标准河内问题的有趣说明:总和(2 n-1 )= 2 n - 1

答案 2 :(得分:1)

我在我的博客中用C实现了这种解决方案的解决方案。我希望附上一个链接,可能对某人有用。 Modified tower of hanoi problem with one or more disks of same size

编辑:所以在算法课程的大学里,我们遇到了一个问题,即如果n个磁盘堆具有相同大小的顶部或底部磁盘,那么答案会有什么变化。问题是后者扩展:我们给出了s类型的磁盘大小,每种大小类型都有特定数量的磁盘。我们必须编写一个C代码来查找具有这些条件的最小移动。所以我做了一些数学计算,修改了河内问题解决方案的原始塔。

这是在我的博客中。另外,我也为更复杂的河内问题塔写了代码。