代码之家  ›  专栏  ›  技术社区  ›  Sarah Collins

河内塔-Python中的中途求解算法

  •  2
  • Sarah Collins  · 技术社区  · 7 年前

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

    我知道有递归算法随时可用,但这不是我要搜索的。 我正在搜索一些算法,这些算法可以从用户解决问题的地方一直到,然后从那里继续解决问题。 有什么想法吗?

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

    以下是迄今为止我的代码(我排除了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 回复  |  直到 7 年前
        1
  •  5
  •   Matt Timmermans    7 年前

    要从任意位置求解河内塔楼,可以使用类似于从标准起始位置求解的标准解的递归过程。

    它只是需要更一般一点。

    编写递归过程 移动磁盘(maxSize,targetPeg) 以大小移动所有磁盘<= 最大尺寸 到销钉 targetPeg公司 ,如下所示:

    1. 查找最大的磁盘 m级 因此 m、 大小(<=最大尺寸 m级 在…上 targetPeg公司 。如果没有这样的磁盘,则返回,因为所有大小为<= 最大尺寸 已经在正确的位置。

    2. 允许 源PEG 在什么地方 m级 当前为,并让 其他PEG 做一个不是 源PEG targetPeg公司

    3. 呼叫 移动磁盘(m.size-1,otherPeg) 以递归方式清除较小的磁盘。

    4. 移动 m级 从…起 源PEG targetPeg公司

    5. 呼叫 移动磁盘(m.size-1,targetPeg) 递归地将较小的磁盘放在它们所属的位置。

    在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