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?