这是练习:
令v和w为有向图G =(V,E)中的两个顶点 . 设计线性时间算法以找到v和w之间的不同最短路径(不一定是顶点不相交)的数量 . 注意:G中的边缘未加权
对于这个消费税,我总结如下:
-
这是一个有向图
-
它要求 the number of different shortest paths . 首先,路径应该是最短的,然后可能存在不止一条这样的最短路径,其长度相同 .
在v和w之间 -
,因此应该计算v到w和w到v .
-
线性时间 .
-
图表未加权 .
从以上几点来看,我有以下想法:
-
我不需要使用Dijkstra’s Algorithm,因为图表没有加权,我们试图找到所有最短路径,而不仅仅是单个路径 .
-
我为最短路径的数量维持了
count
-
我想先从v使用BFS并保留
global level
信息 -
我每次增加
global level
,然后BFS达到一个新的水平 -
我还保留
shortest level
信息,以获取最短路径 -
我第一次在旅行时遇到w,我将
global level
分配给shortest level
和count++
; -
只要
global level
等于shortest level
,每次遇到w时我都会增加count
. -
如果
global level
变得比shortest level
大,我终止了旅行,因为我正在寻找最短的路径而不是路径 . -
然后我再次做2到8,对于w
我的算法是否正确?如果我做v到w然后w到v,那还是被认为是线性时间吗?
8 回答
以下是对此的一些想法 .
证明:如果有多条路径通过同一个顶点进入
x
,那么显然有多种方式通过x
. 这很简单 . 现在让我们假设只有一种方法通过每个顶点进入x
(最大值) .如果之前遇到过x,则当前路径都不能为另一条最短路径做出贡献 . 由于之前遇到过x,所以可以跟随的所有路径将比前一个最短路径长至少一个 . 因此,这些路径都不能对总和做出贡献 .
这意味着我们最多只遇到一次节点并完成 . 所以正常的BFS就好了 .
这可以编译成一个非常简单的算法,主要是BFS .
你的算法在图表上打破了
所有边缘从左向右指向 . 它计算两条路径,一条通过
1
,另一条通过2
,但是1
和2
都可以通过八条不同的最短路径从v
到达,总共十六条 .正如qrqrq所示,您的算法在某些图表上失败,但BFS的想法很好 . 相反,维护一个大小为
|V|
的数组,您将其初始化为零;在z[i]
中保持距离小于level
的已发现顶点i
的最短路径数 . 还要维护一个大小为|V|
的数组d
,使得d[i]
是从v
到顶点i
的距离(如果该距离小于level
) . 初始化level
为0,d[v]
为0,z[v]
为1(从v
到v
有一条长度为0的路径),并将d
的所有其他条目设置为-1
,将z
的所有其他条目设置为0
.现在,只要您在BFS中遇到
i
到j
的边缘,那么:如果
d[j] = -1
,则设置d[j] := level
和z[j] := z[i]
.如果
d[j] = level
,则设置z[j] := z[j] + z[i]
.否则,什么都不做 .
原因是对于从
v
到i
的每条最短路径,从v
到j
有一条最短路径 . 这将给出从线性时间内v
到每个顶点的最短路径数 . 现在再次这样做,但从w
开始 .这个算法对我来说是正确的 .
如你所知,BFS是一个线性时间(
O(N)
)搜索因为时间T
在最坏的情况下,完成它需要T = C + a * N
,其中N
是节点数,C
,a
是任何固定常量 .在您的情况下,执行两次搜索 - 首先从
v
到w
,然后从w
再到v
- 是(最差)2T
或2C + 2a * N
,如果您定义新的C' = 2C
,则还满足线性时间要求O(N)
a' = 2a
,因为C'
和a'
都是固定常量 .上面的代码为我提供了本文中提到的所有类型图表的正确结果 . 基本上它是BFS遍历的边缘回调 .
dist [start] = 0;方式[开始] = 1;
休息所有顶点dist [x] = numberOfVertices; //这超出了可能的最大限度
BFS(g,start);
如果[end]不为零,则表示路数,dist [end]表示最短距离 .
Incase方式[end] == 0表示从头开始无法到达终点 .
如果这里有任何环洞,请告诉我 .
Simplest solution by changing BFS:
count(v)= 0,count(s)= 1.对于v的每个邻居u,如果(d(v)1 == d(u)),则count(u)= count(v) . 现在重置所有内容并从末端顶点执行相同操作 .
我能这样做吗?
我使用BFS遍历,直到到达目标顶点并保持水平
一旦我到达目的地级别,我使用级别表如下
从关卡表开始,我开始遍历计算父路径到路径中顶点的数量(第一次它将是目标顶点) .
在每一步,我将在该特定级别找到的不同父级的数量乘以我可以具有的最短路径到目标顶点 .
我向上移动水平,只考虑落入我路径的节点,并将每个级别找到的 distinct parents 的数量相乘,直到达到0级 .
这有用吗?
请检查一下这里给出的好解释:
https://www.geeksforgeeks.org/number-shortest-paths-unweighted-directed-graph/
简而言之,我们可以修改任何最短路径算法,并且当更新步骤到来时,增加一个计数器,用于当前路径提议具有与该时刻之前发现的最短路径相同的长度时先前发现的最短路径的数量 .
在特定情况下,当它是未加权的图形或所有边缘的恒定权重时,最简单的方法是修改BFS .