我正在写一个sokoban解算器,用于娱乐和练习,它使用一种简单的算法(类似于BFS,但有点不同)。
现在我想估计它的运行时间(O和omega)。但需要知道如何计算网络中从顶点到另一个的非循环路径的计数。 实际上,我想要一个表达式来计算m * n顶点矩阵的两个顶点之间的有效路径计数。
有效路径:
例如,这是一个有效的路径:
alt text http://megapic.ir/images/f1hgyp5yxcu8887kfvkr.png
但这不是:
alt text http://megapic.ir/images/wnnif13ir5gaqwvnwk9d.png
我们需要一种方法来查找两个顶点 a 和 b 之间所有非循环路径的计数。
欢迎对解决方法和技巧的评论。
答案 0 :(得分:4)
计算图表中简单路径数量的一般问题是#P完成。一些#P完全问题具有完全多项式随机化近似方案,有些则没有,但您声称对近似不感兴趣。也许有一种方法可以利用网格结构,就像计算Tutte多项式一样,但我对如何做到这一点没有任何想法。
答案 1 :(得分:4)
不是解决方案,但也许你可以进一步思考这个想法。问题是你还需要计算获得所有路径的最长路径。对于一般图形,longest path problem是NP完全的,因此即使对于相对较小的图形(8x8和更大),它也会花费很长时间。
想象一下,起始顶点位于顶部,左上角,末端顶点位于矩阵的右下角。
每次我将前一次计算的结果与当前路径数相结合。对于这样的平面图可能有一个非常接近的公式,也许甚至有很多理论,但我太愚蠢......
您可以使用以下Java(抱歉,我不是c ++专家: - /)片段来计算更大矩阵的可能路径:
public static void main(String[] args) {
new Main(3, 2).start();
}
int xSize;
int ySize;
boolean visited[][];
public Main(int maxX, int maxY) {
xSize = maxX;
ySize = maxY;
visited = new boolean[xSize][ySize];
}
public void start() {
// path starts in the top left corner
int paths = nextCell(0, 0);
System.out.println(paths);
}
public int nextCell(int x, int y) {
// path should end in the lower right corner
if (x == xSize - 1 && y == ySize - 1)
return 1;
if (x < 0 || y < 0 || x >= xSize || y >= ySize || visited[x][y]) {
return 0;
}
visited[x][y] = true;
int c = 0;
c += nextCell(x + 1, y);
c += nextCell(x - 1, y);
c += nextCell(x, y + 1);
c += nextCell(x, y - 1);
visited[x][y] = false;
return c;
}
=&GT;
这意味着您可以(仅在理论上)计算从MxM矩阵的任何位置到右下角的所有可能路径,然后使用此矩阵快速查找路径数。 Dynamic programming(使用之前的计算结果)可能会加快一些速度。
答案 2 :(得分:3)
项目Euler上存在类似但不太普遍的问题:http://projecteuler.net/index.php?section=problems&id=237
我认为论坛中描述的一些解决方案可以扩展到解决您的一般情况。这是一个相当困难的问题,特别是对于你的一般情况。
要访问他们的论坛,首先需要解决问题。我不会在这里发布答案,也不会链接到列出答案的某个网站,这个网站可以通过搜索非常明显的内容在Google上轻松找到。
答案 3 :(得分:2)
这是数学中的一个开放性问题,直接应用于化学和物理学,用于模拟聚合物键。最早的一些工作是在曼哈顿计划(核弹二战)期间完成的。
更为人所知的是自我避免行走问题。
我在我的大学数学系度过了一个夏天,研究了一种称为枢轴算法的蒙特卡罗算法,以近似给定长度n
的自躲避步行数量的渐近拟合的参数。
请参阅Gordon Slade的优秀书籍“The Self Avoiding Walk”,以便广泛报道迄今为止用于解决此问题的各种技术。
这是一个非常复杂的问题,我想知道你的动机是什么。也许你可以找到一个更简单的模型,因为Self Avoiding Walks并不简单。
答案 4 :(得分:1)
显示边缘的矩阵是否有效?考虑构建一个显示边缘位置的矩阵,即。 [a,b] = 1&lt; =&gt; a-> b是图中的边,否则为0。现在,将此矩阵提升为各种幂,以显示使用n个步骤在顶点之间存在多少种方法,然后将它们相加以得到结果。这只是解决问题的一种方法,可能还有其他方法来解决问题。
我想知道这是否属于MathOverflow,作为另一个想法
是的,一旦你有一个零矩阵你就可以在你的情况下停止取幂,3之后没有很多地方可去,但从1到3的路径将是直接的和经过的路径2,所以在找到全零之前,只有几个矩阵可以加在一起。
我认为应该有一种方法来计算n ^(n + 1)的界限,其中n是图中顶点的数量,它表示一个停止点,就像那个点,每个顶点将被访问过一次。我不确定如何从循环路径中解决问题,或者可以假设图形没有循环?