如何查找图中两个节点之间直到给定数量的中间节点之间的所有路径?
我有一个巨大的有向图,约有一百万个节点和超过一千万条边。边缘未加权。该图是一个类似小世界的图。事实上,我看到每个节点(平均)通过三个中间节点连接到另一个节点。
给定这个图,你能想到一种快速算法,它返回起始节点和目标节点之间的所有路径(没有循环),但最多只能返回给定的最大数量 N 的中间节点(在我的情况下,N 大多数时候将是0 到 3 之间)?
I have a huge directed graph with about a million nodes and more than ten million edges. The edges are not weighted. The graph is a small-world like graph. In fact I see that every node is (on average) connected to another node over three intermediate nodes.
Given this graph can you think of a fast algorithm that returns all paths (without cycles) between a start and a destination node, but only up to a given maximum number N of intermediate nodes (and in my case N most of the time will be between 0 and 3)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您的图是无向的,您肯定会想要进行双向广度优先搜索。对于长度为 2 的路径,从起始节点和结束节点枚举边并查看它们相交的位置。对于长度为 3 的路径,从度数较小的终点开始 2 深度,在度数较大的节点上深度 1 层。
由于您的图是有向的,因此您可能还想保留反向边,以便可以执行相同的操作。
If your graph was undirected, you would certainly want to do a bidirectional breadth first search. For length 2 paths, enumerate edges from the start node and the end node and see where they intersect. For the length 3 paths, go 2 deep from the end point with smaller degree, and one deep on the node with greater degree.
Since your graph is directed, you might want to also keep reverse edges so you can do the same trick.
也许同时从两个方向呼吸第一?获取 A 的邻居和 B 的邻居。如果还没有找到链接,请将 A 添加到“a 的邻居”,将 B 添加到“B 的邻居”,然后查找两个集合之间的任何链接。
为了将其扩展至超过三个链接,“A/B 的邻居”列表需要包含更多内容。您将无法在内存中执行此操作 - 您需要一个临时表
(如果您在插入语句中检查循环,则不需要跟踪深度),
当存在任何
Don' 时,您已经找到了一条路径完成后别忘了清理桌子!将这一切作为一个事务完成并回滚可能是最简单的方法。
Perhaps breath-first from both directions at once? Take neighbours of A, and neighbours of B. if you haven't found a link yet, add A to "neighbours of a" and B to "neighbours of B", then find any link between the two sets.
To extend it a bit further than three links, the "neighbours of A/B" lists need to contain a bit more. You will not be able to do it in-memory - you'll need a scratch table with
(you don't need to track depth if you check for loops in your insert statement)
you have found a path when there exists any
Don't forget to clean out the table when you are done! Doing it all as one transaction and rolling it back might be the easiest way.