解决奈特';带回溯的s教程(javascript)

解决奈特';带回溯的s教程(javascript),javascript,backtracking,Javascript,Backtracking,我试图用javascript编写一个算法,用回溯法解决骑士之旅的问题,但它不起作用。基本上,函数应该输出一个名为VISISTED的数组,其中包含每个移动的位置。但是,没有将任何位置附加到数组,该数组保持为[[0,0]]。这是我的密码。有线索吗 var unit = 75; function m1(position) { position[0] += unit; position[1] += 2*unit; return [position[0],position[1]]} function m

我试图用javascript编写一个算法,用回溯法解决骑士之旅的问题,但它不起作用。基本上,函数应该输出一个名为VISISTED的数组,其中包含每个移动的位置。但是,没有将任何位置附加到数组,该数组保持为[[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;

} 
var单位=75;
函数m1(位置){position[0]+=unit;position[1]+=2*单元;return[position[0],position[1]}
函数m2(位置){position[0]-=单元;position[1]+=2*单元;return[position[0],position[1]}
函数m3(位置){position[0]+=2*单位;position[1]+=unit;return[position[0],position[1]}
函数m4(位置){position[0]=2*单元;position[1]+=unit;return[position[0],position[1]}
函数m5(位置){position[0]+=单元;position[1]-=2*单元;return[position[0],position[1]}
函数m6(位置){position[0]-=unit;position[1]-=2*unit;return[position[0],position[1]}
函数m7(位置){position[0]+=2*单元;position[1]=unit;return[position[0],position[1]}
函数m8(位置){position[0]-=2*单元;position[1]-=unit;return[position[0],position[1]}
var移动=[m1、m2、m3、m4、m5、m6、m7、m8];
var currentPosition=[0,0];
访问的变量=[currentPosition];
功能骑士(当前位置)
{
var j;
if(承诺(当前职位))
{
如果(已访问。长度==64)
{
回访;
} 
其他的
{
对于(j=0;j=0&&
currentPosition[1]<600&¤tPosition[1]>=0&&
isVisited(当前位置,已访问))
{
返回true;
}否则{
返回false;
}
} 
函数isvisted(position,visted)//visted是大小为2([x,y]的数组中大小为n的数组
{//currentPosition是一个大小为2的数组([x,y])

对于(var i=0;i你必须后退一步:你甚至还没有整理好回溯算法,你已经将你显示的电路板与算法要求的电路板混为一谈了。最好的办法是重新开始,解决算法,然后担心它的显示。有了这种想法,你应该用伪代码fi来解决算法rst,然后将该伪代码转换为JavaScript。(提示:在代码中,您似乎从未更改当前位置。)

我看到的整个过程是这样的:

findAllKnightsTours:
  for every board position
    set path = empty
    set board = all false
    findKnightsTour(currentPosition, path, board)
将路径作为堆栈非常好。每次搜索它以查看是否访问了一个正方形是一件痛苦的事情,因此我会使用一个单独的“板”。板应该是一个布尔值矩阵(false==未访问,true=访问),尽管为了简单起见,我会使用一个简单的数组

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转换留给读者作为一个简单的练习。

Hi Aeon,欢迎来到Stack Overflow?我可以问一下这是不是家庭作业吗?嗨,谢谢。是的。这是一个额外的学分家庭作业。如果失败,你的函数isVisited和Promission不会返回false。现在你的isVisited只检查第一个位置。返回false必须是你的
for()
。注意。你在数组上使用
+=
,我认为这不起作用。