【问题标题】:Query regarding dijkstra algorithm关于dijkstra算法的查询
【发布时间】:2014-12-29 12:01:47
【问题描述】:

我正在尝试查找数据集中两个节点之间的最短路径。一世 实现了dijkstra算法并用它来证明 给定两个节点(例如:Andrew_Card 和 Dick_Cheney)没有 在源和目的地之间存在一条路径。但是,我发现 我的程序被操作系统杀死了。

调试后发现问题可能与资源有关 在 RAM 中分配。至于dijkstra算法,如果节点数, n=16,375,503,则空间需求为

 n*n = 16,375,503 * 16,375,503 > 10^{14}. 

要在内存中运行这个算法,我们至少需要

(10^{14} * 4) / (1024 * 1024 * 1024) = 10^5 GB  (approximately equal)
of RAM.  

因此,无法使用以下方法找到最短路径 dijkstra 如果我们打算在内存中保留一个大的连接图。 如果我错了,请纠正我,因为我一直坚持这个问题?或者如果我应该检查其他可能的原因,那么也请指出它。

我用 C++ 实现了程序

没有。边数=25,908,132

【问题讨论】:

  • 图有多少条边?
  • 没有。边数=25,908,132
  • 你真的需要 Dijkstra 来证明不存在吗?简单的 BFS 还不够吗?
  • Dijksta 的内存消耗量很大,如果您确信这是导致您的问题的原因,请考虑更改搜索算法。例如尝试迭代深化算法en.wikipedia.org/wiki/Iterative_deepening_depth-first_search。它既完整又优化
  • 我会支持@user2040251 的回答。由于您只有 2M 条边和 1M 节点,因此您可以使用大约 100 万个条目的邻接列表,每个条目平均长度为 2 条记录。这意味着内存需求很可能低于 1G,而不是 10^5 G。如果您使用 64 位 c++ 编译器和正确的数据结构,内存应该根本不是问题。

标签: c++ algorithm dijkstra


【解决方案1】:

如果您只需要两个节点之间的距离,请使用 A* 之类的内容。

但如果你在做所有点的最短路径,那么你肯定会被O(n^2) 空格所困。你正在寻找O(n^2) 的答案——所以你真的不能做得比必须存储所有答案更好。

【讨论】:

  • A* 和 Dijkstra 相似,只是 Dijkstra 不使用启发式算法。 A* 是 Dijkstra 的一个特例,如果他使用 Dijkstra,很可能没有可用的启发式算法。
  • 他说O(n^2) tho - 我的印象是他在做全对子。仅用于单一来源的 Dijkstra 也是 O(n)
  • @AndersNK,Dijkstra 是 A* 的一个特例,而不是相反。
  • 使用 A* 需要有一个可接受的启发式 - 如果您没有一个可接受的启发式,则不能使用 A*,但必须使用 Dijkstra 或其他搜索方法。 @Avakar,是的,我知道我切换了这两个 - 抱歉(无法编辑)!
【解决方案2】:

如果边数相对较少(以便所有边都可以放入主内存),您可以使用邻接表存储图形。它需要O(V + E) 内存,而不是O(V^2)。此外,您可以将 Dijkstra 算法与优先级队列一起使用。它适用于稀疏图(它具有O(E log V) 时间复杂度)。这种方法应该适用于具有大约2 * 10^7 顶点和边的图(一个好的实现可以很容易地放入主内存并运行不超过几分钟)。

【讨论】:

    【解决方案3】:

    为了确保您的程序确实内存不足,请将您的调用点包装在一个 try-catch 块中,并查看您是否收到 std::bad_alloc 异常。在你看到你正在捕获的异常之前,不要假设你的程序的哪一部分失败了

    就寻找两个节点之间的最短路径而言,您可能应该查阅更多文献以找到最适合您的用例的算法。

    A*:http://en.wikipedia.org/wiki/A*_search_algorithm

    收缩层次结构:http://algo2.iti.kit.edu/schultes/hwy/contract.pdf

    【讨论】:

    • 如果它在Liniux上,它可能会被OOM杀手终止而不会抛出异常。
    【解决方案4】:

    您应该找到减少节点数量的方法。您的节点数很高。您可以使用 Voronoi 图来减少节点数。

    【讨论】:

      【解决方案5】:

      改进的可能是将顶点存储在优先级队列中一次。并且更新优先级队列,而不是一次又一次地将同一个顶点添加到优先级队列中。

      【讨论】:

        猜你喜欢
        • 2013-08-11
        • 2021-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-12
        相关资源
        最近更新 更多