代码之家  ›  专栏  ›  技术社区  ›  RED SOFT ADAIR

你所知道的最快的Dijkstra实现是什么(用C++)?

  •  12
  • RED SOFT ADAIR  · 技术社区  · 17 年前

    我最近确实将Dijkstra算法的第三个版本附加到了我的项目中,用于单源最短路径。

    My Data是一个液压网络,每个节点有1到5个顶点。这相当于一张街道地图。我对已经加速的算法进行了一些修改(对所有剩余节点使用排序列表),现在在很短的时间内找到了相同的结果。我寻找这样的东西已经有一段时间了。我想知道这样的实施是否已经存在。

    我无法解释结果中的细微差异。我知道Dijkstra不是启发式的,但所有的实现似乎都是正确的。更快的解决方案具有更短路径的结果。我只使用双精度数学。

    MyListType toDoList; // List sorted by smallest distance 
    InsertAllNodes(toDoList);
    while(! toDoList.empty())
    {
        MyNodeType *node = *toDoList.first();
        toDoList.erase(toDoList.first());
        ...
    }
    

    MyListType toDoList; // List sorted by smallest distance 
    toDoList.insert(startNode);
    while(! toDoList.empty())
    {
        MyNodeType *node = *toDoList.first();
        toDoList.erase(toDoList.first());
        for(MyNeigborType *x = node.Neigbors; x != NULL; x++)
        {
            ...
            toDoList.insert(x->Node);
        }
    }
    

    看起来,这种修改将运行时间减少了一个数量级,而不是一个指数级。它将我的运行时间从30秒缩短到2秒以下。我在任何文献中都找不到这种修改。很明显,原因在于排序列表。插入/擦除在100000个元素时的性能要差得多,而用一只手装满。

    boost graph lib wikipedia .

    5 回复  |  直到 17 年前
        1
  •  11
  •   MSalters    17 年前

        2
  •  3
  •   Luixv    17 年前

    也许我没有回答你的问题。我的观点是,当你的问题有更有效的算法时,为什么要使用Dijkstra。如果你的图充满了三角形属性(它是欧几里得图)

    (节点a到节点b的距离加上节点b到节点c的距离大于节点a到结点c的距离),然后可以应用a*算法。 实施不是主要问题。要使用的算法确实很重要。

        3
  •  2
  •   eddykent    9 年前

    我想说两点: 1) Dijkstra vs A*

    对于欧几里德图这样的情况,A*效果很好,因为启发式函数很容易定义(例如,可以简单地使用欧几里德距离)。然而,对于非欧几里德图,定义启发式函数可能更难,错误的定义可能会导致非最优路径。

    因此,dijkstra比A*有优势,因为它适用于任何一般图(除了A*在某些情况下更快)。很可能某些实现可以互换使用这些算法,从而产生不同的结果。

        4
  •  1
  •   Nick    17 年前

    Dijkstra的所有“真”实现每次都应该返回相同的结果。

        5
  •  0
  •   Dietrich Epp    17 年前

    这将取决于很多事情。你对输入数据了解多少?它是密集的还是稀疏的?这将改变算法的哪个版本最快。

    如果它是密集的,就使用矩阵。如果它是稀疏的,你可能想看看更有效的数据结构来找到下一个最近的顶点。如果你有更多关于数据集的信息,而不仅仅是图连接,那么看看不同的算法是否会像a*那样更好地工作。

    问题是,该算法没有“最快”的版本。