How to optimize Knight's tour algorithm?

前端 未结 4 830
难免孤独
难免孤独 2021-01-30 18:40

I code the Knight\'s tour algorithm in c++ using Backtracking method. But it seems too slow or stuck in infinite loop for n > 7 (bigger than 7

4条回答
  •  走了就别回头了
    2021-01-30 18:41

    Here is my 2 cents. I started with the basic backtracking algorithm. It was waiting indefinitely for n > 7 as you mentioned. I implemented warnsdorff rule and it works like a magic and gives result in less than a second for boards of sizes till n = 31. For n >31, it was giving stackoverflow error as recursion depth exceeded the limit. I could find a better discussion here which talks about problems with warnsdorff rule and possible further optimizations.

    Just for the reference, I am providing my python implementation of Knight's Tour problem with warnsdorff optimization

    
    
        def isValidMove(grid, x, y):
                maxL = len(grid)-1
                if x  maxL or y  maxL or grid[x][y] > -1 :
                        return False
                return True
    
        def getValidMoves(grid, x, y, validMoves):
                return [ (i,j) for i,j in validMoves if isValidMove(grid, x+i, y+j) ]
    
        def movesSortedbyNumNextValidMoves(grid, x, y, legalMoves):
                nextValidMoves = [ (i,j) for i,j in getValidMoves(grid,x,y,legalMoves) ]
                # find the number of valid moves for each of the possible valid mode from x,y
                withNumNextValidMoves = [ (len(getValidMoves(grid,x+i,y+j,legalMoves)),i,j) for i,j in nextValidMoves]
                # sort based on the number so that the one with smallest number of valid moves comes on the top
                return [ (t[1],t[2]) for t in sorted(withNumNextValidMoves) ]
    
    
        def _solveKnightsTour(grid, x, y, num, legalMoves):
                if num == pow(len(grid),2):
                        return True
                for i,j in movesSortedbyNumNextValidMoves(grid,x,y,legalMoves):
                #For testing the advantage of warnsdorff heuristics, comment the above line and uncomment the below line
                #for i,j in getValidMoves(grid,x,y,legalMoves):
                        xN,yN = x+i,y+j
                        if isValidMove(grid,xN,yN):
                                grid[xN][yN] = num
                                if _solveKnightsTour(grid, xN, yN, num+1, legalMoves):
                                        return True
                                grid[xN][yN] = -2
                return False
    
        def solveKnightsTour(gridSize, startX=0, startY=0):
                legalMoves = [(2,1),(2,-1),(-2,1),(-2,-1),(1,2),(1,-2),(-1,2),(-1,-2)]
                #Initializing the grid
                grid = [ x[:] for x in [[-1]*gridSize]*gridSize ]
                grid[startX][startY] = 0
                if _solveKnightsTour(grid,startX,startY,1,legalMoves):
                        for row in grid:
                                print '  '.join(str(e) for e in row)
                else:
                        print 'Could not solve the problem..'
    
    
    

提交回复
热议问题