我正在尝试为以下任务找到时间有效的算法
给定一组页面A,B,C,D,E,其中A,B,C,D可以是起始点但是E 永远是一个终点。以下表示页面之间的连接 (A,B),(A,B),(A,C),(A,E),(B,A),(B,C),(C,A),(C,E),(C ,D),(D,E),(D,A)。 现在,如果我选择
A
作为起点而E
作为终点,那么我必须找到所有A
和E
之间的可能路径,其路径长度在时间效率上最多为4 方式。因此,A
和E
之间的最大路径长度为4的所有可能路径都是A-&GT,E
A-> D-&GT,E
A-> C-> D-&GT,E
A-> B-> C-&GT,E
A-> B-> C-&GT,E
A-> B-> A-> e 还有更多
注1: 两个相同顶点之间的两条边被视为不同,顶点的顺序也很重要。 Graph中可以存在一个循环。
注2: 打破无限循环搜索的唯一方法是通过限制路径长度的最大限制。
答案 0 :(得分:2)
这个问题可以通过动态编程来解决。
我们可以通过两个参数表示每个步骤,当前节点和已经采取的步骤数(节点,步骤)
伪代码:
int[][]dp;
int getNumberOfWay(int node, int step){
if(step == 4)
if(node == end node)
return 1;
return 0;
if(already visit this step)
return dp[node][step];
int result = 0;
if(node == end node)
result++;
for(node that has edges coming from this node)
result += getNumberOfWay(next node, step + 1);
return dp[node][step] = result;
}
时间复杂度为O(4 * E * N),E为边数,N为节点数。
注意:如果我们从末端节点而不是4个起始节点遍历图形,也可以改善问题。
答案 1 :(得分:1)
可以使用矩阵乘法来解决。
我们说A[i][j]
表示从i
走到j
的总路径,然后由于组合的乘法规则,我们有A'[i][j] = A[i][k] * A[k][j]
。我们可以看到这个公式是矩阵乘法的形式。
因此,我们可以使用A
行和列构建矩阵N
,其中N
是总页数。然后A[i][j]
表示从j
开始前往i
的初始方式。例如,您问题的初始A
将为:
A B C D E
A 0 2 1 0 1
B 1 0 1 0 0
C 1 0 0 1 1
D 1 0 0 0 1
E 0 0 0 0 0
接下来,我们只需要计算A[0..3][4] + A^2[0..3][4] + A^3[0..3][4] + A^4[0..3][4]
,其中A^k
表示A代表k
的力量。
使用矩阵乘法的好处是它可以扩展到更一般的问题:使用恰好K步骤可以形成从i到j的路径数量?。
在这种情况下,我们只需要计算A^k
,可以使用exponentiation by squaring加速并在O(log k) * O(N^3)
中求解,其中O(N^3)
是矩阵乘法的复杂性