河内塔 - 用Python解决中途算法

时间:2018-03-11 13:25:02

标签: python algorithm solver

有可能中途解决河内的塔吗?我已经做了大量的研究,寻找能够解决用户配置问题的代码,但我还没找到。这是一项任务,我要求代码从用户停止解决的地方接管并继续为用户解决,而不必将拼图重置为方块。

我知道有一些递归算法可供使用,但这不是我正在寻找的。 我正在寻找可以从用户解决的地方接管的算法,然后从那里继续解决。 有什么想法吗?

到目前为止,我已经提出了一种算法,将优化的算法(通过递归完成)存储到一个数组中,然后检查用户的输入是否等于数组中的任何输入,然后继续从那里解决。但是,问题在于在优化算法数组中找不到用户的配置。

以下是我目前的代码(我已经排除了stack.py代码):

def solveHalfway(n, start, end, middle, count):
    gameInstance.stackA = [3,2]
    gameInstance.stackB = []
    gameInstance.stackC = [1]
    loopCounter = 0 # initialise loopCounter as 0
    moveCounter = 0 # initialise the move index the user is stuck at
    indicator = 0 # to indicate whether the user's config equals the solution's config
    while loopCounter < arrayOfStacks.size(): # while loopCounter size has not reached the end of arrayOfStacks
        if loopCounter != 0 and loopCounter % 3 == 0:  # if 3 stacks have been dequeued
            moveCounter += 1
            if gameInstance.getUserConfig() == tempStack.data:  #check whether user's config is equal to the solution's config
                indicator += 1
                print "User is stuck at move: ", moveCounter  #this will be the current move the user is at
                while arrayOfStacks.size() != 0: # while not the end of arrayOfStacks
                    correctMovesStack.push(arrayOfStacks.dequeue())  # add the moves to correctMovesStack
                    if correctMovesStack.size() == 3: # if 3 stacks have been dequeued
                        print "Step:", moveCounter , correctMovesStack.data # display the step number plus the correct move to take
                        moveCounter+=1 # increase move by 1
                        while correctMovesStack.size() != 0: # if correct moves stack isn't empty
                            correctMovesStack.pop() # empty the stack
                return
            else:
                while tempStack.size() != 0: # check if tempStack is empty
                    tempStack.pop()  # empty tempStack so that it can be used for the next loop
            tempStack.push(arrayOfStacks.dequeue()) #dequeue from arrayOfStacks for a total of 3 times and push it to tempStack
        else:
            tempStack.push(arrayOfStacks.dequeue()) #dequeue from arrayOfStacks for a total of 3 times and push it to tempStack
        loopCounter +=1 # increase loop counter by 1
    if indicator == 0:
        moveWith3Towers(noOfDisks, stackA, stackC, stackB, count)
    print indicator

1 个答案:

答案 0 :(得分:4)

要从任意位置解决河内塔,您可以使用类似于标准起始位置的标准解决方案的递归程序。

它必须更加通用。

编写一个递归过程 moveDisks(maxSize,targetPeg),将所有大小为&lt; = maxSize 的磁盘移动到peg targetPeg ,像这样:

  1. 找到最大的磁盘 m ,以便 m.size&lt; = maxSize m 不 em> on targetPeg 。如果没有这样的磁盘,则返回,因为所有大小为&lt; = maxSize 的磁盘已经在正确的位置。

  2. sourcePeg 成为当前 m 的挂钩,并让 otherPeg 成为不是的挂钩 sourcePeg targetPeg

  3. 递归调用 moveDisks(m.size-1,otherPeg)以使较小的磁盘不受影响。

  4. m sourcePeg 移至 targetPeg

  5. 以递归方式调用 moveDisks(m.size-1,targetPeg),将较小的磁盘放在它们所属的位置。

  6. 在python中,我会这样写。请注意,我对游戏状态使用了不同的表示形式,该算法更适合此算法,并且不允许任何非法位置:

    #
    # Solve Towers of Hanoi from arbitrary position
    #
    # diskPostions -- the current peg for each disk (0, 1, or 2) in decreasing
    #                 order of size.  This will be modified
    # largestToMove -- move this one and all smaller disks
    # targetPeg -- target peg for disks to move
    #
    def moveDisks(diskPositions, largestToMove, targetPeg):
        for badDisk in range(largestToMove, len(diskPositions)):
    
            currentPeg = diskPositions[badDisk]         
            if currentPeg != targetPeg:
                #found the largest disk on the wrong peg
    
                #sum of the peg numbers is 3, so to find the other one...
                otherPeg = 3 - targetPeg - currentPeg
    
                #before we can move badDisk, we have get the smaller ones out of the way
                moveDisks(diskPositions, badDisk+1, otherPeg)
    
                print "Move ", badDisk, " from ", currentPeg, " to ", targetPeg
                diskPositions[badDisk]=targetPeg
    
                #now we can put the smaller ones in the right place
                moveDisks(diskPositions, badDisk+1, targetPeg)
    
                break;
    

    测试:

    > moveDisks([2,1,0,2], 0, 2)
    Move  3  from  2  to  0
    Move  1  from  1  to  2
    Move  3  from  0  to  1
    Move  2  from  0  to  2
    Move  3  from  1  to  2