转移到移动磁盘的河内塔+ 1或-1

时间:2017-07-24 07:13:08

标签: python towers-of-hanoi

我可以很容易地复制河内塔的问题,但这里只是移动盘+ 1或-1钉/塔的扭曲,即从钉/塔1它可以到达空间2而不是3。

到目前为止,我已经为经典情况提供了这个递归工作代码,并努力插入如上所述的移动约束

def printMove(fr, to):
    print('Move from ' + str(fr) + ' to ' + str(to))

def Towers(n, fr, to, mid):
    if n == 1:
        printMove(fr, to)
    else:
        Towers(n-1, fr, mid, to)
        Towers(1, fr, to, mid)
        Towers(n-1, mid, to, fr)

n = input("Input the number of disc: ")
print(Towers(int(n), 'P1', 'P2', 'P3'))

有人可以帮助我在算法上可视化constriaint

2 个答案:

答案 0 :(得分:2)

frto挂钩不相邻时,您需要将问题细分为两个步骤。一个从fr移动到mid挂钩,另一个移动到to挂钩。这可以通过额外的递归案例来完成:

def Towers(n, fr, to, mid):
    if abs(fr - to) > 1:
        Towers(n, fr, mid, to)
        Towers(n, mid, to, fr)
    elif n == 1:
        printMove(fr, to)
    else:
        Towers(n-1, fr, mid, to)
        Towers(1, fr, to, mid)
        Towers(n-1, mid, to, fr)

请注意,新案例需要在基本案例之前进行测试,因为您不能一次移动多个钉子。

我正在检查相邻钉子的方式要求他们有数字标签(所以你用Towers(4, 1, 2, 3)之类的东西来称呼它。如果您正在使用其他标签系统(例如字符串,在您在问题中进行的调用),则需要添加一些额外的逻辑,让代码知道哪些挂钩是相邻的,哪些不是。

答案 1 :(得分:0)

在河内塔的普通版中,我们将该问题划分为:-
1)将上部(n-1)塔放在辅助挂钩中。 (2 ^(n-1)-1个步骤)
2)将第n个塔置于目的地挂钩中。 1步
3)将上(n-1)个塔放在目标挂钉中。 (2 ^(n-1)-1步)
总共(2 ^(n-1)-1 + 1 + 2 ^(n-1)-1)= 2 ^ n-1步 在这里,我们将放置在目标挂钉或辅助挂钉中,因为我们可以将任何磁盘从任何地方直接放置到任何地方,所有挂钉都是对称的。

但是在此受限版本中,如果我们将三个钉分别标记为1,2和3,则必须考虑两种情况(因为所有钉都不等效,并且顺序与先前的情况不同)。
注意: a)如果您不想使用1,2,3作为挂钩编号(也许使用名称),则只需编写一些额外的代码行。
b )这里的“第n个磁盘”或“第n个磁盘”是指按大小升序排列的第n个磁盘。

1)如果fr!=2to!=2,则我们必须将整个塔楼移到最远的桩钉(即桩钉1到桩钉3,反之亦然)。假设我们要将塔从1移到3。接下来将是步骤

i)在移除上(n-1)个塔并且这些(n-1)个塔不能位于相邻的桩(即桩2或mid)上之前,我们无法移动第n个磁盘,因此我们将(n-1)塔移动到桩3(to)。 (3 ^(n-1)-1个步骤)
ii)然后将第n个磁盘移动到钉2(mid)(1步)。
iii)再次将(n-1)塔移动到钉1(fr)。 (3 ^(n-1)-1个步骤)
iv)然后将第n个磁盘移至钉3(to)。 (1步)
v)最后,再次将(n-1)塔移至桩3(to)。 (3 ^(n-1)-1步)
总计(3 ^(n-1)-1 +1 + 3 ^(n-1)-1 +1 + 3 ^(n-1)- 1步= 3 ^ n-1步)

2)如果fr==2to==2,则我们必须将塔筒移到相邻的桩钉上。例如,如果我们要在钉2上移动n个磁盘,而要移动到钉3:-在达到最终配置时,它将通过一个配置,其中(n-1)-tower在钉1上,第n个磁盘在钉2。因此,
i)我们必须将(n-1)塔放在钉2的钉1上。否则,我们无法将第n个磁盘移动到钉3。
ii)移动将第n个磁盘固定到钉3。
iii)最后,将(n-1)塔移到钉3上。

no=int(input("Enter Number of disks "))

def move_tower(n,fr,to,mid):
    if (n>=1)and(fr!=2)and(to!=2):
        move_tower(n-1,fr,to,mid)
        print("Moving disk ",n,"from ",fr," to ",mid)
        move_tower(n-1,to,fr,mid)
        print("Moving disk ",n,"from ",mid," to ",to)
        move_tower(n-1,fr,to,mid)
    elif (n>=1)and((fr==2)or(to==2)):
        move_tower(n-1,fr,mid,to)
        print("Moving disk ",n,"from ",fr," to ",to)
        move_tower(n-1,mid,to,fr)

# move_tower(no,1,2,3)
move_tower(no,1,3,2)

要进行编码,了解最终配置和初始配置之间的中间配置会很有帮助。为此,请检查以下链接:
i> Normal version of Tower of Hanoi is similar to counting numbers in binary.
ii> This constrained version of Tower of Hanoi is similar to counting numbers in ternary base 3.另外,在将塔从钉1移到钉3时,我们必须通过所有可能的(合法)磁盘配置,即3 ^ n配置。