我了解Dijkstra的算法是什么,但我不知道它为什么有效。
选择下一个顶点进行检查时,为什么Dijkstra的算法选择权重最小的顶点?为什么算法不访问所有顶点,为什么不随便选择一个顶点呢?
您可以将Djikstra的算法视为注水算法(即修剪的广度优先搜索)。在每个阶段,目标都是以尽可能最低的成本覆盖整个图表。假设您在填充区域的边缘有一个顶点,并按照距离列出了它们:
v0 <= v1 <= v2 <= v3 ...
可能有一种更便宜的到达顶点的方法v1吗?如果是这样,则该路径 必须 经过v0,因为没有未经测试的顶点会更近。因此,您检查顶点v0以了解到达的位置,检查通过任何路径v0是否更便宜(到任何其他顶点仅一步之遥)。
v1
v0
如果以此方式解决问题,则可以确保距离都是最小的,因为您始终会精确检查可能导致最短路径的那个顶点。找到最短路径,或者排除最短路径,然后移至下一个顶点。因此,您可以确保每步消耗一个顶点。
而且您停止时不做任何多余的工作,因为当目标顶点占据“我是最小的” v0插槽时,您会停止。
让我们看一个简单的例子。假设我们正在试图从获取1到12的乘法和节点之间的成本是你必须乘以数量。(我们将顶点限制为从1到的数字12。)
1
12
我们从开始1,然后乘以该值即可到达任何其他节点。因此,如果您一步一步执行,则节点2具有成本2,3具有成本3,… 12具有成本12。
2
3
现在,如果存在从到的免费链接,则2可以通过(不知道结构的)路径12最快。没有,但是如果有,那将是最快的。所以我们检查一下。而且我们发现我们可以达到cost ,to for 等等。因此,我们有一个成本表,如下所示:2``12``2``4``2``6``3
2``12``2``4``2``6``3
3 4 5 6 7 8 9 10 11 12 // Vertex 3 4 5 5 7 6 9 7 11 8 // Best cost to get there so far.
好了,现在也许我们可以得到12从3免费的!更好地检查。我们发现,3*2==6这样的成本6是成本3加2,并9为正3,而且12是加4。
3*2==6
6
9
4
4 5 6 7 8 9 10 11 12 4 5 5 7 6 6 7 11 7
很公平。现在我们进行测试4,我们看到我们可以付出8额外的努力2,并12付出额外的努力3。同样,到达的成本12不超过4+ 3= 7:
8
7
5 6 7 8 9 10 11 12 5 5 7 6 8 7 11 7
现在我们尝试5和6迄今为止–no改进。这给我们留下了
5
7 8 9 10 11 12 7 6 8 7 11 7
现在,第一次,我们看到越来越到的成本8是 少 比让到的成本7,所以我们最好检查有没有一些免费的方式去12从8。没有-用整数根本无法到达- 因此我们将其丢弃。
7 9 10 11 12 7 8 7 11 7
现在,我们看到这12和剩下的任何一条路一样便宜,因此到达的成本12必须是7。如果我们到目前为止一直跟踪最便宜的路径(仅在严格改善的情况下才替换路径),我们会发现这3*4是第一种最便宜的命中方法12。
3*4