C++ 从A[A,b]到A[c,d]的不同非循环路径的计数?

C++ 从A[A,b]到A[c,d]的不同非循环路径的计数?,c++,algorithm,math,graph-theory,discrete-mathematics,C++,Algorithm,Math,Graph Theory,Discrete Mathematics,为了好玩和练习,我正在编写一个sokoban解算器,它使用了一个简单的算法(有点像BFS) 现在我想估算它的运行时间(O和ω)。但需要知道如何计算网络中从一个顶点到另一个顶点的非循环路径数。 实际上,我需要一个表达式来计算m*n顶点矩阵的两个顶点之间的有效路径数 有效路径: 访问每个顶点0或1次 没有电路 例如,这是一个有效路径: 但这不是: 所需要的是一种方法来查找两个顶点a和b之间所有非循环路径的计数 欢迎对解决方法和技巧提出意见。显示边缘的矩阵是否有效?考虑建立一个矩阵来显示边是什

为了好玩和练习,我正在编写一个sokoban解算器,它使用了一个简单的算法(有点像BFS)

现在我想估算它的运行时间(O和ω)。但需要知道如何计算网络中从一个顶点到另一个顶点的非循环路径数。 实际上,我需要一个表达式来计算m*n顶点矩阵的两个顶点之间的有效路径数

有效路径:

  • 访问每个顶点0或1次
  • 没有电路
例如,这是一个有效路径:

但这不是:

所需要的是一种方法来查找两个顶点a和b之间所有非循环路径的计数


欢迎对解决方法和技巧提出意见。

显示边缘的矩阵是否有效?考虑建立一个矩阵来显示边是什么,即[a,b]=1 a->b是图中的边,否则为0。现在,将这个矩阵提高到不同的幂,以显示使用n个步骤在顶点之间存在多少种方法,然后将它们相加得到结果。这只是解决问题的一种方法,可能还有其他方法来解决问题

我不知道这是否属于另一个想法


是的,一旦你有了一个零矩阵,你就可以停止求幂了,就像你的例子一样,在3之后没有很多地方可以去,但是从1到3的路径是直接的,并且是通过2的路径,所以在找到全部零之前,只有几个矩阵可以加在一起



我认为应该有一种方法来计算n^(n+1)的界,其中n是图中的顶点数,表示一个停止点,因为在该点之前,每个顶点都会被访问一次。但是,我不知道如何解决循环路径的问题,或者可以假设图形没有循环?

在project Euler上有一个类似但不太普遍的问题:

我认为论坛中描述的一些解决方案可以扩展到解决您的一般情况。这是一个相当困难的问题,尤其是对于你的一般情况


要访问他们的论坛,首先需要解决这个问题。我不会在这里发布答案,也不会链接到某个列出答案的网站,通过搜索一些非常明显的东西,你可以很容易地在谷歌上找到这个网站。

计算图表中简单路径的数量的一般问题已经完成。有些#P-完全问题有完全多项式随机逼近方案,有些没有,但您声称对逼近不感兴趣。也许有一种方法可以利用网格结构,就像计算Tutte多项式一样,但我不知道如何做到这一点。

不是一个解决方案,但也许你可以进一步思考这个想法。问题是,您还需要计算可能的最长路径以获得所有路径。对于一般的图来说,它是NP完全的,所以即使对于相对较小的图(8x8或更大),它也会得到很长的时间

假设起点顶点位于矩阵的左上角,终点顶点位于矩阵的右下角

  • 对于1x2矩阵,只有一条可能的路径
  • 2x2矩阵=>2***1**路径=>2
  • 3x2矩阵=>2***2**路径=>4
  • 3x3矩阵=>2***4**+2*2路径=>12
  • 3x4矩阵=>2***12**+12+2路径=>38
每次我结合前面计算的结果来计算当前的路径数。对于这样一个平面图,可能有一个很接近的公式,也许有很多理论,但我太笨了,不能这么做

可以使用以下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;
}
publicstaticvoidmain(字符串[]args){
新的主管道(3,2).start();
}
int-xSize;
内化;
布尔访问[][];
公用干管(int-maxX,int-maxY){
xSize=maxX;
ySize=maxY;
visited=新布尔值[xSize][ySize];
}
公开作废开始(){
//路径从左上角开始
int path=nextCell(0,0);
System.out.println(路径);
}
公共int nextCell(int x,int y){
//路径应在右下角结束
if(x==xSize-1&&y==ySize-1)
返回1;
如果(x<0 | | y<0 | | x>=xSize | | y>=ySize | |已访问[x][y]){
返回0;
}
访问[x][y]=真;
int c=0;
c+=nextCell(x+1,y);
c+=nextCell(x-1,y);
c+=nextCell(x,y+1);
c+=nextCell(x,y-1);
访问[x][y]=错误;
返回c;
}
=>

  • 4x4=>184
  • 5x5=>8512
  • 6x6=>1262816
  • 7x7(即使是这个简单的案例也需要很多时间!)=>575780564

这意味着您可以(仅在理论上)计算从MxM矩阵的任何位置到右下角的所有可能路径,然后使用该矩阵快速查找路径数。(使用以前的计算结果)可以加快速度。

这是数学中的一个开放性问题,可以直接应用于化学和物理,用它来模拟聚合物键。在这方面最早的一些工作是在曼哈顿计划(二战核弹)期间完成的

它更被称为自我回避行走问题

我在大学数学系花了一个夏天研究了一种称为pivot算法的蒙特卡罗算法,以逼近给定长度
n
的自回避行走次数的渐近拟合参数

请参阅戈登·斯莱德(Gordon Slade)的优秀著作《到目前为止用于解决此问题的技术类型》中的广泛内容

这是一个非常复杂的问题,我想知道你考虑这个问题的动机是什么。也许你可以找到一个更简单的模型来满足你的需求,因为自我回避行走一点也不简单。

num