问题在于:
假设两个人在社交网站上注册,如何决定他们是否有联系?我的分析(阅读更多):实际上,问题是寻找 - 图中A到B的最短路径。我认为BFS和Dijkstra的算法在这里工作,时间复杂度完全相同(O(V + E)),因为它是一个未加权的图,所以我们不能利用优先级队列。因此,一个简单的队列可以解决问题。但是,它们都没有解决这个问题:找到它们之间的路径。
此时Bidrectrol应该是更好的解决方案。
答案 0 :(得分:3)
要找到两者之间的路径,您应该从广度优先搜索开始。首先查找A
的所有邻居,然后查找A
等所有邻居的所有邻居。一旦B
被命中,您不仅拥有从A
到B
的路径A
,但你也有最短这样的路径。
Dijkstra's algorithm岩石,你可以通过从两端工作来加快速度,即找到B
的邻居和{{1}}的邻居,并进行比较。
如果您进行深度优先搜索,那么您一次只能跟踪一条路径。这会慢得多。
答案 1 :(得分:2)
一种方法是使用联盟查找,添加所有链接union(from,to)
,如果find(A) is find(B)
为True,则A
和B
已关联。这样可以避免递归搜索,但它实际上会计算所有对的连接性,并且不会为您提供连接A
和B
的路径。
答案 2 :(得分:1)
我认为真正的标准是:A和B之间至少有N条路径比K短,或者A和B分别连接。我会选择K = 3和N接近5,即有5个共同的朋友。
答案 3 :(得分:1)
如果您使用dfs查找两个人是否在社交网络上连接,那么这将花费太长时间!
您已经认识这两个人,因此您应该使用Bidirectional Search.。但是,对于像社交网站一样大的图形,简单的双向搜索是不够的。你将不得不使用一些启发式方法。维基百科页面有一些链接。
您也可以使用A* search.来自维基百科:“A *使用最佳优先搜索并查找从给定初始节点到一个目标节点的最低成本路径(在一个或多个可能的节点中)目标)。”
编辑:我建议A *因为“执行双向搜索的额外复杂性意味着如果我们有合理的启发式算法,A *搜索算法通常是更好的选择。”因此,如果您无法形成合理的启发式,那么请使用双向搜索。 (形成一个好的启发式方法绝非易事;)。)
答案 4 :(得分:0)
注意:回答已编辑。
任何方法都可能最终变得很慢。如果您需要重复执行此操作,最好找到图形的连接组件,之后任务变为一个简单的O(1)操作:如果两个人在同一个组件中,则它们是连接的。
请注意,首次查找连接的组件可能会很慢,但是在将新的边/节点添加到图表时保持更新很快。
有多种查找连接组件的方法。
一种方法是构造图的拉普拉斯算子,并查看其特征值/特征向量。零特征值的数量为您提供连接组件的数量。相应特征向量的非零元素给出属于各个组件的节点。
另一种方式是:
创建节点转换表。数组的元素n
包含节点n
转换为的节点的索引。
循环遍历图表中的所有边(i,j)
(表示i
和j
之间的关联):
i
和j
转换为哪个节点。我们按k
和l
表示结果。更新条目k
以使其转换为l
。更新条目i
和j
也指向l
。再次循环遍历表格,并更新每个条目以将直接指向递归转换为的节点。
现在,同一个连接组件中的节点将在转换表中具有相同的条目。因此,要检查两个节点是否已连接,只需检查它们是否转换为相同的值。
每次向图表添加新节点或边缘时,都需要更新转换表,但此更新将比表格的原始计算快得多。