最便宜的路径算法

时间:2010-02-05 14:52:38

标签: algorithm path

我学会了动态编程算法来找到从A到B的“最便宜”路径。每个子路径都有相关的成本。

每个角落使用
计算 D(i,j).value = min( (D(i-1,j).value + D(i,j).x), (D(i,j-1).value + D(i,j).y))
其中x和y是节点左侧和节点下方路径的成本。

我现在无法在最佳时间内找出可能最便宜的路径数量。

有什么建议吗?

http://www.freeimagehosting.net/uploads/f6e0884a2d.png

7 个答案:

答案 0 :(得分:8)

您正在寻找Dijkstra's algorithm。它是一种图搜索算法,可以解决具有非负边缘路径成本的图的单源最短路径问题,从而生成最短路径树。

答案 1 :(得分:2)

您描述的动态编程方法称为DAG shortest path。它仅适用于有向非循环图(即没有循环的图)。它的渐近运行时间是O(V + E)(其中V和E分别是顶点和边的数量),这比Dijkstra算法快。

我不确定,但您是否在询问如何计算长度等于最短路径的路径数?

您可以通过在计算最短路径的长度时保留前任信息来实现。当您移动到节点j时,存储所有对(i,j),使得从i到j是最短路径的一部分。实现此目的的一种方法是添加两个字段,D(x,y).optimalUp和D(x,y).optimalRight(数据类型boolean),指示如果通过进入(x,y)输入(x,y),是否获得最佳解决方案分别向上或向右。例如,如果从(x,y-1)向上行,则将D(x,y).optimalUp设置为true,从而得到最便宜的路径。

然后,您可以使用动态编程进行第二次传递以计算最便宜的路径数。添加另一个字段,比如说D(x,y).count(整数),它以最便宜的方式保存从A到(x,y)的方式。有两种方法可以达到(x,y):Via(x-1,y)和(x,y-1)。如果可以通过经过(x,y-1)实现到(x,y)最便宜的路径,则只应将(x,y-1)的计数加到(x,y)的计数上。同样的原则适用于(x-1,y)。

然后我们再次发生:

D(x,y).count =
    D(x,y).optimalUp   ? D(x,y-1).count : 0
  + D(x,y).optimalDown ? D(x-1,y).count : 0

(?:是C / C ++ / Java中的条件运算符。)

从你的照片来看,你的图表似乎是一个网格。注意只向上或向右行进不需要导致最短的路径。在下图中,从A到B的最短路径为8,但如果只是向右和向上,则不能达到12以上。

x -1-- x -1-- B
|      |      |
1      9      9
|      |      |
x -1-- x -1-- x
|      |      |
9      9      1
|      |      |
A -1-- x -1-- x

由于这被标记为家庭作业,我现在不会提供比此更多的细节。尽管如此,这应该是正确的方向(如果我已正确理解你的问题)。不过,请随时提出后续问题。

答案 2 :(得分:1)

看起来您正在使用图表,其中节点是2D网格上的点,每个节点都有一个指向其上方节点的边缘,另一个节点指向右侧节点。

我不认为只应用Dijkstra的算法就可以了。它找到了一个最便宜的成本路径,并且实际上没有办法修改它以找到所有最短路径。

由于这是一个特殊的图形(即有向和非循环),您可以使用简单的重复计算最便宜路径的数量,前提是您知道最便宜路径的成本。注意

number_paths(i,j)=number_of_paths(i-1,j)+number_of_paths(i,j-1)

即。来自任何节点的路径数是来自上方和右侧节点的路径数。 (这省略了当前节点是目标节点以及目标节点无法从当前节点到达的基本情况。)

唯一需要的是修改它以仅计算那些最便宜的路径。现在,我们已经知道最便宜的路径有一些成本X.我们可以使用它来增加我们的重复,以便它只计算最便宜的路径。在起始节点,我们知道剩余路径的成本是X.从任何相邻节点到起始节点(即从其正上方和右侧的节点),因此成本是Xe,其中e是这些节点之间的边缘成本。此规则适用于已知到达当前节点的成本的任何节点。因此,我们知道当我们到达目的地节点并且该节点的值为0时,我们已经遍历了最便宜的路径(即我们已经减去了形成最便宜路径的边缘的所有成本)。

因此我们可以增加我们的重复,以便我们保留3个值而不是2个,即路径的坐标和剩余成本(实际上转换为3D图形的相同问题,其中第三个维度是成本)。起始节点的格式为(x_start,y_start,cost),目标节点的格式为(x_end,y_end,0)。我们的复发看起来像:

paths(x,y,cost_left)=
                 0         if x_end,y_end is unreachable from x,y or cost_left<0
                 1         if x==X-end and y==y_end and cost_left==0
                 paths(x-1,y,cost_left-edge(x,y,x-1,y))+paths(x,y-1,cost_left-edge(x,y,x,u-1))   otherwise

算法的复杂性应该是O(n m C),其中n和m是网格的维度,C是最便宜路径的成本。

答案 3 :(得分:0)

查看维基百科上的Hillclimbing和A-star算法。

答案 4 :(得分:0)

答案 5 :(得分:0)

A *是最好的,可能对您有用。

答案 6 :(得分:0)

尝试寻找“最短路径”算法,但有一个问题。

许多最短路径搜索使用估计距离目标作为启发式算法,通常必须满足某些条件。例如,A *使用距离目标估计函数,并且如果它永远不会低估到目标的距离,则保证找到最短路径。由于您正在寻找具有最低任意成本的路径,因此您不会轻易获得那种启发式方法。此外,您知道路径的长度,因此迭代加深等算法不会有用。

任何确定性算法,如Dijkstra's algorithm,都应该可以正常工作。

相关问题