用任意放置的磁盘解决河内塔?

时间:2020-09-09 19:49:03

标签: algorithm recursion towers-of-hanoi

我正在尝试使用递归来解决河内塔的问题。我知道,如果一开始所有的圆环都在同一座塔上,那么有一种很好的算法可以通过查看序列中每个步骤的二进制表示来解决该问题。

但是,让我们假设我们想解决一开始混乱的环的河内塔问题。令R i 表示半径为i的圆环。假设最初R 5 和R 2 在极A上,R 4 在极B上,R 3 和R 1 位于极C上,如下所示:

 **           *
***** ****   ***
  A     B     C

如果目标是将所有环移到B极,那么第一步是什么?而且,更笼统地说,您将如何解决河内塔的这种变体?

1 个答案:

答案 0 :(得分:2)

好玩的问题!我们可以使用类似于解决常规河内塔难题的递归见解来解决此问题。

让我们按大小为磁盘1、2、3、4,...,n编号。现在,假设我们要结束主轴B上的每个磁盘。看看磁盘n在哪里。如果磁盘n位于主轴B上,则我们不需要移动它-它对其他磁盘的运动不会有任何影响,因为它的放置绝不会妨碍任何运动。到那时,我们只需要(递归)将其他n-1个磁盘移到主轴B上,并且基本上可以忽略磁盘n。

另一方面,如果磁盘n位于另一个主轴上(例如,主轴A或主轴C),那么我们将需要将其移至主轴B。但是唯一可行的方法是,如果所有其他磁盘都位于不在磁盘n上(然后磁盘n不能移动)或在主轴B上(那么磁盘n不能在那里移动)。这意味着我们得到以下基本设置:

move all disks of size n or less to spindle X:
    # Base case: If we need to move zero disks, there's nothing to do.
    if n == 0: return

    # Recursive case 1: If disk n is already on spindle X, we don't need to
    # do anything fancy! Just move the other disks.
    if disk n is on spindle X:
        recursively move all disks of size n-1 to spindle X
        return

    # Recursive case 2: If disk n isn't on spindle X, it's on some other
    # spindle Y. That means all other disks need to get to the third 
    # spindle Z before we can move disk n.
    recursively move all disks of size n-1 to spindle Z, as defined above.
    move disk n to spindle X.

    # Now, move all the remaining disks back on top of disk n.
    recursively move all disks of size n-1 to spindle X.

此解决方案的一个优点是,基本上每个步骤都是强制执行的-没有决定要做什么的事情,也没有捷径可走。因此,可以保证找到最快的移动磁盘的方法。

此外,该解决方案很好地概括了针对河内塔的标准递归算法。请注意,如果所有磁盘都以标准配置启动,那么递归情况1永远不会触发,我们将获得与以前完全相同的算法。