我一直在尝试在javascript中实现递归回溯迷宫生成算法。这些是在阅读了关于here
主题的大量帖子后完成的虽然算法的递归版本没什么问题,但iterative equivalent让我感到难过。
我以为我理解了这个概念,但是我的实现显然会产生错误的结果。我一直试图找出一个可能导致它的错误,但我开始相信我的问题是由逻辑失败引起的,但当然我没有看到。
我对迭代算法的理解如下:
创建一个堆栈,其中包含单元格状态的表示。
每个表示都包含该特定单元格的坐标,以及访问相邻单元格的方向列表。
当堆栈不为空时,迭代堆栈顶部的方向,测试相邻的单元格。
如果找到有效的单元格,请将其放在堆栈的顶部并继续该单元格。
这是我的递归实现(注意:keydown要前进):http://jsbin.com/urilan/14
这是我的迭代实现(再一次,keydown向前迈进):http://jsbin.com/eyosij/2
感谢您的帮助。
编辑:如果我的问题不明确,我道歉。我会尝试进一步解释我的问题。
运行迭代解决方案时会发生各种意外行为。首先,该算法在回溯之前不会耗尽所有可用选项。相反,它似乎是在剩下一个有效单元时随机选择单元格。但总的来说,这一运动似乎并不是随机的。
var dirs = [ 'N', 'W', 'E', 'S' ];
var XD = { 'N': 0, 'S':0, 'E':1, 'W':-1 };
var YD = { 'N':-1, 'S':1, 'E':0, 'W': 0 };
function genMaze(){
var dirtemp = dirs.slice().slice(); //copies 'dirs' so its not overwritten or altered
var path = []; // stores path traveled.
var stack = [[0,0, shuffle(dirtemp)]]; //Stack of instances. Each subarray in 'stacks' represents a cell
//and its current state. That is, its coordinates, and which adjacent cells have been
//checked. Each time it checks an adjacent cell a direction value is popped from
//from the list
while ( stack.length > 0 ) {
var current = stack[stack.length-1]; // With each iteration focus is to be placed on the newest cell.
var x = current[0], y = current[1], d = current[2];
var sLen = stack.length; // For testing whether there is a newer cell in the stack than the current.
path.push([x,y]); // Store current coordinates in the path
while ( d.length > 0 ) {
if( stack.length != sLen ){ break;}// If there is a newer cell in stack, break and then continue with that cell
else {
var cd = d.pop();
var nx = x + XD[ cd ];
var ny = y + YD[ cd ];
if ( nx >= 0 && ny >= 0 && nx < w && ny < h && !cells[nx][ny] ){
dtemp = dirs.slice().slice();
cells[nx][ny] = 1;
stack.push( [ nx, ny, shuffle(dtemp) ] ); //add new cell to the stack with new list of directions.
// from here the code should break from the loop and start again with this latest addition being considered.
}
}
}
if (current[2].length === 0){stack.pop(); } //if all available directions have been tested, remove from stack
}
return path;
}
我希望这有助于为您解决问题。如果仍然缺少任何物质,请告诉我。
再次感谢。
答案 0 :(得分:3)
我在javascript方面不是很好,但我尝试将你的递归代码实现为迭代。您还需要在堆栈上存储For
索引。所以代码看起来像:
function genMaze(cx,cy) {
var dirtemp = dirs; //copies 'dirs' so its not overwritten
var path = []; // stores path traveled.
var stack = [[cx, cy, shuffle(dirtemp), 0]]; // we also need to store `for` indexer
while (stack.length > 0) {
var current = stack[stack.length - 1]; // With each iteration focus is to be placed on the newest cell.
var x = current[0], y = current[1], d = current[2], i = current[3];
if (i > d.length) {
stack.pop();
continue;
}
stack[stack.length - 1][3] = i + 1; // for next iteration
path.push([x, y]); // Store current coordinates in the path
cells[x][y] = 1;
var cd = d[i];
var nx = x + XD[cd];
var ny = y + YD[cd];
if (nx >= 0 && ny >= 0 && nx < w && ny < h && !cells[nx][ny]) {
dtemp = dirs;
stack.push([nx, ny, shuffle(dtemp), 0]);
}
}
return path;
}
答案 1 :(得分:0)
这个小代码是否也有帮助?
/**
Examples
var sum = tco(function(x, y) {
return y > 0 ? sum(x + 1, y - 1) :
y < 0 ? sum(x - 1, y + 1) :
x
})
sum(20, 100000) // => 100020
**/
function tco(f) {
var value, active = false, accumulated = []
return function accumulator() {
accumulated.push(arguments)
if (!active) {
active = true
while (accumulated.length) value = f.apply(this, accumulated.shift())
active = false
return value
}
}
}
积分,解释和更多信息都在github https://gist.github.com/1697037
不修改代码有好处,因此它也可以应用于其他情况。希望有所帮助:)