我目前正试图通过使用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
答案 0 :(得分:3)
我会怀疑所花费的时间:
Marshal.load(Marshal.dump board)
另一种方法是使用单一的电路板副本。
在巡演开始时你设置:
board[x][y] = current_move
所以如果在巡演结束时你用以下方式清除它:
board[x][y] = 0
然后你不需要复制董事会。
请注意,骑士有8个合法动作!
尝试添加:
{x: x+2, y: y+1}