用回溯解决骑士之旅(javascript)

时间:2011-06-26 21:39:16

标签: javascript backtracking

我正在尝试用javascript写一个算法来解决使用Backtracking的Knight's Tour问题,但它不起作用。基本上,该函数应该输出一个名为 visited 的数组,该数组包含每个移动的位置。但是,没有位置附加到数组,其仍为[[0,0]]。这是我的代码。任何线索?

var unit = 75;

function m1(position) { position[0] += unit; position[1] += 2*unit; return [position[0],position[1]]}
function m2(position) { position[0] -= unit; position[1] += 2*unit; return [position[0],position[1]]}
function m3(position) { position[0] += 2*unit; position[1] += unit; return [position[0],position[1]]}
function m4(position) { position[0] -= 2*unit; position[1] += unit; return [position[0],position[1]]}
function m5(position) { position[0] += unit; position[1] -= 2*unit; return [position[0],position[1]]}
function m6(position) { position[0] -= unit; position[1] -= 2*unit; return [position[0],position[1]]}
function m7(position) { position[0] += 2*unit; position[1] -= unit; return [position[0],position[1]]}
function m8(position) { position[0] -= 2*unit; position[1] -= unit; return [position[0],position[1]]}

var moves = [m1, m2, m3, m4, m5, m6, m7, m8];   
var currentPosition = [0, 0];
var visited = [currentPosition];

function knightour(currentPosition)
{

    var j; 

    if (promising(currentPosition))
    {

        if (visited.length == 64)
        {
            return visited;
        } 
        else 
        {
            for (j=0; j<moves.length; j++)
            {
                context.drawImage(knight, currentPosition[0], currentPosition[1]);
                alert("NEXT");
                visited.push(moves[j](currentPosition));
                knightour(currentPosition);
            }
        }
    } 
}  

function promising(currentPosition)
{
    if (currentPosition[0] < 600 && currentPosition[0] >= 0 &&
        currentPosition[1] < 600 && currentPosition[1] >= 0 &&
        isVisited(currentPosition, visited))
        {
        return true;
    } else {
        return false;
    }

} 

function isVisited(position, visited)               // visited is an array of size n of array of size 2 ([x,y])
{                                                       // currentPosition is an array of size 2 ([x,y])
    for (var i=0; i<visited.length; i++)
    {
        if (position[0] == visited[i][0] && position[1] == visited[i][1])
        {
            return true;
        }
    }
    return false;

} 

谢谢。

1 个答案:

答案 0 :(得分:2)

你必须退后一步:你甚至没有整理回溯算法,而且你已经将你显示的电路板与算法所需的电路板混为一谈。最好的办法是重新开始,解决算法,然后担心所有的显示。有了这个想法,你应该首先使用伪代码解决算法,然后将该伪代码转换为JavaScript。 (提示:在您的代码中,您似乎永远不会改变当前位置。)

我看到整个过程如下:

findAllKnightsTours:
  for every board position
    set path = empty
    set board = all false
    findKnightsTour(currentPosition, path, board)

将路径作为堆栈很好。每次搜索一个方块都是一个痛苦,所以我会使用一个单独的“板”。该板应该是一个布尔值矩阵(假= =未访问,真=访问),但为简单起见,我将使用一个简单的数组。

findKnightsTour(position, path, board):
  push position onto path
  set board[position] to true

  if path.length == 64
    print out path
  else
    for each of the eight moves
      next = calculate new position based on move
      if validPosition(next, board)
        findKnightsTour(next, path, board)

  set board[position] to false
  pop position off path

validPosition例程检查位置是否在板限制范围内并且当前未被访问(即,为真)。

如果您查看此例程,您将看到它将当前位置添加到路径和板上,执行操作,然后将其从路径和板中删除。这是算法的回溯部分:保存一些状态,尝试一些东西,然后恢复旧状态。

我将JavaScript转换作为Reader的简单练习。