【问题标题】:Using Dijkstra to detect multiple shortest paths使用 Dijkstra 检测多条最短路径
【发布时间】:2018-05-18 13:04:29
【问题描述】:

给定一个加权有向图,如何修改 Dijkstra 算法以测试给定节点对之间是否存在多个最低成本路径?

我目前的算法如下:(感谢 Weiss)

/**
 * Single-source weighted shortest-path algorithm. (Dijkstra) 
 * using priority queues based on the binary heap
 */
public void dijkstra( String startName )
{
    PriorityQueue<Path> pq = new PriorityQueue<Path>( );

    Vertex start = vertexMap.get( startName );
    if( start == null )
        throw new NoSuchElementException( "Start vertex not found" );

    clearAll( );
    pq.add( new Path( start, 0 ) ); start.dist = 0;

    int nodesSeen = 0;
    while( !pq.isEmpty( ) && nodesSeen < vertexMap.size( ) )
    {
        Path vrec = pq.remove( );
        Vertex v = vrec.dest;
        if( v.scratch != 0 )  // already processed v
            continue;

        v.scratch = 1;
        nodesSeen++;

        for( Edge e : v.adj )
        {
            Vertex w = e.dest;
            double cvw = e.cost;

            if( cvw < 0 )
                throw new GraphException( "Graph has negative edges" );

            if( w.dist > v.dist + cvw )
            {
                w.dist = v.dist +cvw;
                w.prev = v;
                pq.add( new Path( w, w.dist ) );
            }
        }
    }
}

【问题讨论】:

  • 您只想检测多个等价路径(即返回一个布尔值),还是要列出所有等价路径?
  • @pkpnd 我只需要多个最短路径的布尔指标,而不是所有实际路径。

标签: java graph-theory shortest-path dijkstra


【解决方案1】:

将字段prev,上一个顶点的链接替换为集合prevs,并稍微更改代码:

...

        if( w.dist >= v.dist + cvw ) {
            if ( w.dist > v.dist + cvw ) {
                w.dist = v.dist +cvw;
                w.prevs.clear();
            }
            w.prevs.add(v);
            pq.add( new Path( w, w.dist ) );
        }

...

【讨论】:

    【解决方案2】:

    如果你只想找到一个其他的等价路径

    假设您已经运行了一次 Dijkstra 算法以获得最短路径P。您可以在P 中的每条边上添加一个很小的成本epsilon,然后在修改后的图上再次运行Dijkstra 以获得一条新路径P'。如果P 和P' 包含相同的边,那么您可以得出结论P 是唯一的最短路径。否则,我们撤消epsilon 更改并比较P 和P' 的长度。如果长度相等,那么显然P' 是另一个明显的最短路径。否则,P 是唯一的最短路径。

    如果我们想找到所有最短路径

    这样的算法必然是指数时间的。这是因为图可以在两个节点之间具有指数级多的等成本路径。例如,考虑图表:

    A --> B1 --> C --> D1 --> E ...
      \       ->   \       ->
       -> B2 /      -> D2 /
    

    从A 到E 有 4 条路径,如果我们假设所有边的成本相同,那么所有这些路径的总成本都相同。通过重复这种模式,我们可以获得成倍增长的等成本路径。

    【讨论】:

    • 我认为单一的其他等成本路径方法行不通。请核实。我尝试了一个示例,但似乎失败了。
    • @user248884 你能描述一下失败的情况吗?
    • ibb.co/bGk79e 请看图片。虽然 P 和 P' 有相同的边,但它不是唯一的。
    • 您只需将epsilon 添加到 P 的边上。所以在第一张图中,如果 P 是 A->B->D,那么边 BC 和 CD 不应该添加 epsilon。此外,epsilon 应该是一个很小的值,例如 0.01,远小于任何边缘权重。
    • 另外,请参阅en.wikipedia.org/wiki/K_shortest_path_routing 了解其他方法
    猜你喜欢
    • 1970-01-01
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多