5x5网格中所有可能的移动?

时间:2012-02-07 06:43:43

标签: javascript arrays algorithm function formula

s o o o o
o o o o o
o o o o o
o o o o o
o o o o e

我如何计算所有可能的路径,而不使用同一个方格两次,一个人可以从se

我创建了一个网格数组[[1,1] ... [5,5]],但我不知道这是否有用。

我还绘制了可能的方块,并试图创建一个记录并检查大量的垃圾。

我可以在这里使用任何标准配方吗?

5 个答案:

答案 0 :(得分:5)

您可以使用相当多的标准路径寻找算法。

这与javascript无关。

你可以使用一种没有启发式的算法,你不应该停留在第一个解决方案上。

以下是如何做到这一点:

诀窍是你需要将已经访问的方块存储在一个列表中,并检查你是否在每一步都重新访问其中一个。

另一个技巧是你需要在相邻方格之间确定顺序。 (像上/右/下/左。这是一个非常愚蠢的算法,但对于这个特殊情况很好。)

此外,您需要能够识别正方形(可能通过其位置)

考虑一个递归函数(例如将其命名为Visit):

function visit(square) {

    add the square to the pathlist //pathlist is not a list of paths but a list of squares which is the current path

    if (square is the goal) {
        add a copy of the pathlist to the goalslist
    }
    else {
        for (each adjacency in square.adjacencies) { // this can be calculated by adding +1 and -1 to the coordinates, and checking if its overflowing (less then one/more than five)
            if (adjacency is in pathlist) {
                //do nothing we have already been here
            }
            else {
                visit(adjacency)
            }
        }
    }

    remove square from the pathlist!!
}

通过访问(开始)开始这个algorythm。你可以在goallist中得到你的结果,这是一份希望的路径列表。

此外,它只有一半javascript-half伪代码,但很容易从中编写javascript。

编辑:享受解决方案:

<script type="text/javascript">
var start = [1,1],
    goal = [5,5],
    pathList = [],
    solutionList = [],
    solutionCount = 0,
    width = 5,
    height = 5;


function squareInArray(square, array) {
    var i = 0,
        x = square[0], 
        y = square[1];

    for (i = 0; i < array.length; i++) {
        if (x == array[i][0] && y == array[i][1]) {
            return true;
        }
    }
    return false;
}


function visit(square) {
    var i = 0,
        x = square[0], 
        y = square[1],
        adjacencies = [[x-1,y],[x+1,y],[x,y+1],[x,y-1]];

    pathList.push(square);

    if (x == goal[0] && y == goal[1]) {
        var solution = pathList.slice(0); //copy trick
        solutionList.push(solution);
        solutionCount++;
        //alert(solution);
    }
    else {
        for (i = 0; i < adjacencies.length; i++) {
            if (adjacencies[i][0] < 1 || adjacencies[i][0] > width || adjacencies[i][1] < 1 ||adjacencies[i][1] > height) {
                //overflow
            }
            else {
                if (squareInArray(adjacencies[i], pathList)) {
                    //do nothing we have already been here
                }
                else {
                    visit(adjacencies[i]);
                }
            }
        }
    }

    pathList.pop();
}

visit(start);

alert(solutionCount);
</script>
8512个目标。还有人应检查我的代码是否正确。

看看这个小提琴:http://jsfiddle.net/SoonDead/rd2GN/3/

答案 1 :(得分:1)

您可以使用深度优先搜索和回溯来查找所有可能的路径。这个想法很简单,从S开始,然后访问S的任何邻居,然后从该邻居访问任何其他邻居,一旦你回溯从顶点删除了“used”状态,就将顶点标记为“used”,这样你就可以重用它了另一条道路等......一旦你到达E,你就增加路径的数量。必须限制路径,所以我假设你的意思是不使用一个顶点多次的路径,或者你可以有无限循环。

弗兰克提到加泰罗尼亚数字,这确实有效,但仅适用于单调路径,即仅向右/向下或向左/向上的路径。 DP也不起作用,因为这是NP-Hard问题(非多项式时间来找到解决方案并进行验证,因为基本上你需要再次找到所有路径以确保它们匹配)。

答案 2 :(得分:1)

有关此问题的参考和参考书目,以及递归关系,请参阅Weisstein的 MathWorld 中的 Self-Avoiding Walk 。非常不幸的是,我无法理解Abbott和Hanson关于这个问题的文章。

正方形大小的序列的生长速度是强大的。根据{{​​3}},12×12平方的自行走路数量是182413291514248049241470885236,这是一个30位数字!

感谢这个问题,这确实是一个深刻且引人深思的问题。

编辑:如果允许对角线步骤,则数字会更快地增长。由于D. Knuth,这是OEIS序列OEIS A007764。即使对于5×5平方(超过4亿个路径)也很难蛮力。他用来计算这些数字的技术有A140518,称为ZDD。

答案 3 :(得分:1)

如果您使用5x5网格,则有一个简单的数学解决方案。在网格的底部和顶部写下1,然后添加拐角,直到到达终点为止,最后拐角处的数字是路径数。这是假设您只能左右移动。

这里是一个例子:

1 1 1 1 1 1 1 1 1 1 1 o o o o o 1 2 3 4 5 6 1点-1 3 6 10 15 21 1点-1 4 10 20 35 56 1 o o o o o 1 5 15 35 70 126 1 o o o o o 1 6 21 56 126 252

答案是252

您也可以使用阶乘公式(每个右侧和下方的网格数量)!除以(左侧)!除以(缺点)!=路径数。

因此您的方程将看起来像10!除以5!除以5!= 252

请记住,只有当男人只能上下走动时,此方法才有效!

答案 4 :(得分:-2)

2你的广场有多大的力量。在你的情况下2的功率od 5是32.因此有三十二种不同的可能路线。可以使用以下示例来证明该图案化。虽然不可能是0x0的正方形,但从技术上讲,它有一种可能的方法从A到B,因为它已经存在。一个1x1的正方形有两条可能的路线(如果你不相信我画出来并发现它。这种模式非常明显,甚至与PAscal的三角形有关。希望我帮助过。