我正在考虑以下问题(非常粗略的描述):
假设我们有一个图表,其中边缘被分配了一些非负成本,一个起始节点s和一些成本常数C.找出:
N,从到达s那里的最短路径的从开始节点的成本s在任何节点N不大于C.e集合 - 最短路径的成本.基本上Dijkstra有成本约束.
我的主要问题是:图论中这个问题的正确术语是什么?
我一直在关注"可访问性"或"可达性",但这些似乎是错误的关键字.
最后,我正在寻找一种算法,它可以在一个(不可修改的)但相当大的(可能约1亿个边缘)图形上并行地有效地回答许多这样的查询.我想查看文献,但需要提供正确的关键词提示.
更新:我的实际问题如下.
假设我们获得了一个大陆规模的道路网络(模拟为有向图,在边缘和节点上具有一些属性,如果它是行人路或高速公路).边缘成本是旅行时间.
我想回答用户查询,例如:从某个给定位置(图形节点)开始,哪些节点可在1小时内到达?
我也想非常快地(对于许多用户来说,如果可能的话,<200-300ms)(并且如果可能的话,> 200,如果可能)并行地回答这些查询.
我认为应该至少有两种可能的优化:
我自己有一些想法,但我首先要检查文献,以避免重新发明轮子.
您正在处理的问题的正确术语是“最短路径算法”系列。可达性问题(即 Warshal)处理的问题是“节点 A 和 B 之间是否存在路径?” 它有一个二元答案,在这种情况下你不需要权重,你只需要寻找边缘。但是在您的情况下,您需要考虑在每种情况下从节点 A 到节点 B 所需的时间。
现在,没有“完全”适合这个问题,因为 Dijktra's、Floyd's、BFS 或 DFS 上的一个小的变化可以用来解决这个问题,但是由于图的大小,你增加了复杂性,这是很重要的理解如何构建您的解决方案。使用哪种算法取决于您的时间限制和可用硬件的特定组合。
您的问题有 2 种算法解决方案(我假设您已经将所有边存储在某处,并且您可以以某种方式查询该数据库):
在理想(想象)的世界中,您将运行 Floyd 算法,将结果矩阵保存在 Redis 之类的东西中,就是这样,您可以在不到 10 毫秒的时间内处理您的请求,如果客户端数量增加,您可以添加更多 Redis 服务器作为需要,因为图表不太可能经常更改(因为在您的特定问题中您有道路信息)。问题在于解决方案的空间复杂性,最好的一点是一切都是预先计算的,这意味着您对请求的响应时间最短。为了能够实现这种变化,您需要大量空间,即使是一个将数据库存储在磁盘(是磁盘,不是内存)上的 redis 集群和所有带有 SSD 的服务器也应该足够了,当数量增加时,此选项可以很好地扩展并发客户端的数量增长,时间响应非常快。但是,您是否可以使用此解决方案取决于图中节点的数量:即使您需要使用每条边预先计算距离,您也只需要空间来存储 NxN 矩阵,即 N 是图中节点的数量,如果这个矩阵适合 redis,那么你可以使用这个算法并预先计算所有节点之间的所有“距离”(在你的情况下,这是成本的总和,也就是“旅行时间”)。稍后,当您收到请求时,您需要查询生成的矩阵以获取行程时间小于给定值的所有节点,将此矩阵存储在 redis 中时还有一个额外的优化可以让您完全获取节点编号快速使用排序集。即使您需要使用每条边预先计算距离,您也只需要空间来存储 NxN 矩阵,即 N 是图中节点的数量,如果该矩阵适合 redis,那么您可以使用此算法并预先计算所有“距离” (在您的情况下,这是所有节点之间的成本总和,即“旅行时间”)。稍后,当您收到请求时,您需要查询生成的矩阵以获取行程时间小于给定值的所有节点,将此矩阵存储在 redis 中时还有一个额外的优化可以让您完全获取节点编号快速使用排序集。即使您需要使用每条边预先计算距离,您也只需要空间来存储 NxN 矩阵,即 N 是图中节点的数量,如果该矩阵适合 redis,那么您可以使用此算法并预先计算所有“距离” (在您的情况下,这是所有节点之间的成本总和,即“旅行时间”)。稍后,当您收到请求时,您需要查询生成的矩阵以获取行程时间小于给定值的所有节点,将此矩阵存储在 redis 中时还有一个额外的优化可以让您完全获取节点编号快速使用排序集。(在您的情况下,这是所有节点之间的成本总和,即“旅行时间”)。稍后,当您收到请求时,您需要查询生成的矩阵以获取行程时间小于给定值的所有节点,将此矩阵存储在 redis 中时还有一个额外的优化可以让您完全获取节点编号快速使用排序集。(在您的情况下,这是所有节点之间的成本总和,即“旅行时间”)。稍后,当您收到请求时,您需要查询生成的矩阵以获取行程时间小于给定值的所有节点,将此矩阵存储在 redis 中时还有一个额外的优化可以让您完全获取节点编号快速使用排序集。
然后您有第二个解决方案,即修改 Dijktra、BFS 或 DFS 以根据成本修剪搜索,仅此而已。在这种情况下,由于空间复杂度高,您已经放弃了 Floyd,这意味着您的图在节点和边上都相当大。在这种情况下,使用任何算法的变体的解决方案几乎相同,这使得不同的是您如何存储图形。可以修改所有 3 种算法以在您想要的时间内有效响应,但要支持超过 10k 客户端,用于存储图形的数据库会有所不同。在这里你还有另外两个选择:
希望能帮助到你!