我试图找到数据集中两个节点之间的最短路径。一世 实现了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
答案 0 :(得分:14)
如果边缘数量相对较少(所有边缘都可以放入主存储器中),则可以使用邻接列表存储图形。它需要O(V + E)
内存,而不是O(V^2)
。此外,您可以将Dijkstra算法与优先级队列一起使用。它适用于稀疏图(它具有O(E log V)
时间复杂度)。对于具有大约2 * 10^7
个顶点和边缘的图形,这种方法应该可以正常工作(一个好的实现可以很容易地适应主内存并运行不超过几分钟)。
答案 1 :(得分:3)
如果您需要两个节点之间的距离,请使用类似A*
的内容。
但是如果你做的所有点都是最短的路径,那么你肯定会遇到O(n^2)
空间。你找到了O(n^2)
个答案 - 所以你不能真正做到比存储它们更好。
答案 2 :(得分:2)
在确保程序确实内存不足的情况下,将callsite包装在try-catch块中,看看是否收到了std :: bad_alloc异常。在您看到正在捕获的异常之前,不要假设程序的哪个部分失败
在找到两个节点之间的最短路径方面,你可能需要更多的文献来找到最适合你用例的算法。
A *:http://en.wikipedia.org/wiki/A * _ search_algorithm
答案 3 :(得分:2)
您应该找到一种减少节点数的方法。您的节点数量很高。您可以使用Voronoi Diagram来减少节点数。
答案 4 :(得分:0)
改进可能只是将顶点存储在优先级队列中一次。并更新优先级队列,而不是一次又一次地将相同的顶点添加到优先级队列。