使用Warnsdorff规则解决骑士之旅

时间:2017-07-18 18:46:18

标签: ruby algorithm knights-tour

我目前正试图通过使用Warnsdorff规则来改进Knight巡回赛的暴力实施,但是我觉得我不理解算法,因为脚本的执行需要很长时间。我主要是寻找提示,指出我正确的方向,这样我就可以尽可能多地计算出来。谢谢!

这是我的代码:

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

1 个答案:

答案 0 :(得分:3)

优化

我会怀疑所花费的时间:

Marshal.load(Marshal.dump board)

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

在巡演开始时你设置:

board[x][y] = current_move

所以如果在巡演结束时你用以下方式清除它:

board[x][y] = 0

然后你不需要复制董事会。

错误

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

尝试添加:

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