使用 Warnsdorff 规则解决 Knights Tour

Solving Knights Tour using Warnsdorff's Rule

我目前正在尝试使用 Warnsdorff 规则改进 Knight's Tour 的暴力执行,但是我觉得我好像不理解算法,因为脚本的执行需要很长时间。我主要是在寻找提示以指明正确的方向,以便我可以自己尽可能多地解决这个问题。谢谢!

这是我的代码:

class KnightsTour
    def initialize
        board = [nil, nil, nil, nil, nil, nil, nil, nil]
        8.times do |i|
            board[i] = [0, 0, 0, 0, 0, 0, 0, 0]
        end
        tour(0,0,board)
    end

    def tour(x,y,board,current_move=0)
        current_move +=1
        board[x][y] = current_move

        puts board if current_move == 64
        exit if current_move == 64

        ordered_neighbors = 
            neighbors(x,y,board).sort_by { |m| m[:weight] }

        ordered_neighbors.each do |move|
            tour(move[:x], move[:y], Marshal.load(Marshal.dump board), current_move)
        end
        false
    end

    def weight(x,y,board)
        possible = 0
        moves(x,y).each do |move|
            next unless valid_move?(move, board)
            possible +=1
        end
        possible
    end

    def neighbors(x,y,board)
        neighbors = []
        moves(x,y).each do |move|
            next unless valid_move?(move, board)
            neighbors << { weight: weight(move[:x], move[:y], board), 
                                x: move[:x], y: move[:y] }
        end
        neighbors
    end

    def valid_move?(move,board)
        x = move[:x]
        y = move[:y]
        !(board[x] == nil || board[x][y] == nil || 
          board[x][y] != 0 || x < 0 || y < 0)
    end

    def moves(x,y)
        [{x: x+2, y: y-1}, 
         {x: x+1, y: y-2}, 
         {x: x-1, y: y-2}, 
         {x: x-1, y: y+2}, 
         {x: x+1, y: y+2}, 
         {x: x-2, y: y+1}, 
         {x: x-2, y: y-1}]
    end
end

KnightsTour.new

优化

我会怀疑在以下方面花费的时间:

Marshal.load(Marshal.dump board)

另一种方法是使用电路板的单个副本。

游览开始时您设置:

board[x][y] = current_move

因此,如果您在游览结束时使用以下方式清除它:

board[x][y] = 0

那么你应该不需要复印纸板了。

错误

请注意,骑士有 8 个合法移动!

尝试添加:

{x: x+2, y: y+1}