Boost::graph Dijkstra : 最初填充队列

Posted

技术标签:

【中文标题】Boost::graph Dijkstra : 最初填充队列【英文标题】:Boost::graph Dijkstra : initially populating the queue 【发布时间】:2011-10-06 14:42:22 【问题描述】:

我正在使用 boost::graph 及其 Dijkstra 实现。

我想计算从一组顶点到另一组顶点的最短路径。 我不想计算这些集合之间的所有可能路径。

这个想法是这样的:我在一座建筑物中,各个街道都有入口。所以我可以在任何一条街道上开始我的旅程。但我只对最短的感兴趣。

如果我使用自己的 Dijkstra 算法实现,我会执行以下操作:

对于每个起始节点,距离映射到 0 将起始节点添加到优先级队列中。

虽然使用boost::dijkstra_shortest_paths_no_init 将距离图设置为0 很容易,但我不知道如何将节点添加到优先级队列中。 我查看了源代码,这似乎几乎是不可能的。 所以我正在考虑定义我自己的 Combine 函子,如果我到达其中一个起始节点,它将返回 0 距离,但它看起来相当难看。

我可以创建一个虚拟节点,并将虚拟节点的边添加到起始节点。但是,这会触发一些我想避免的并发访问问题。

我是否错过了 boost 库中的一个可能性,或者有人知道一个聪明的解决方法。我也在考虑修补 boost 以允许自定义初始化优先级队列。

【问题讨论】:

没有一个主要的“最短路径”算法计算“所有可能的路径”它们只计算最短路径。 Dijkstra 算法必须计算图中从单个节点到所有其他节点的最短路径,这是其性质的一部分。它没有做任何额外的工作。 而且我确实想要计算所有可能的路径(但存在类似 Floyd–Warshall 的算法)。用多个出发点塞满优先队列并没有错;行为与从虚拟节点到起始节点的零成本边相同) 弗洛伊德-沃沙尔的不计算“所有可能的路径”。它计算所有节点对的最短路径。 【参考方案1】:

我没有使用 boost::graph,我希望对它有更好了解的人会给出更好的答案,但也许你可以创建一个包装现有图的图类型,保持原始图不变,但暴露于该算法包含您的虚拟节点和边缘的视图?如果不是,是否无法复制整个图?

【讨论】:

该图是巴黎地区,有 1,5M 边。所以我不能复制它。不过你的想法还不错。我必须看看在 boost::graph 中实现它有多痛苦 :) @Tristram,这个评论让我对这个问题感到困惑。不能复制是什么意思?我也不太明白这个问题,是不是你的图太大而无法一次遍历? 遍历图没问题,大约10ms(路径比整个图小)。但是,复制图形将消耗大量内存和时间(应用程序是 Web 服务),这是可以接受的。计算 10 次 dijkstra 在时间上会更容易接受 关键是你不应该复制它。只需将它包装在可以添加虚拟顶点的东西中。尽管 dijkstra 实现的附加要求并不容易。

以上是关于Boost::graph Dijkstra : 最初填充队列的主要内容,如果未能解决你的问题,请参考以下文章

删除顶点并再次添加它会导致 boost::graph 崩溃?

如何使用 Boost Graph Library 创建 named_graph?

使用Boost Graph库查找连接的组件,顶点和边缘类型为boost :: listS

使用整数索引访问 boost::graph 中的特定边

12.boost有向无向图邻接表表示

13.boost最小生成树 kruskal_min_spainning_tree