找出每个节点到k个最近节点的距离

时间:2020-10-24 09:41:31

标签: algorithm graph breadth-first-search shortest-path

如果我的问题措辞不清楚,请让我知道,我将尽力改写!

我们得到了一个大型道路网络(> 1,000,000个节点,> 3,000,000个边),该图未加权也没有方向。在此图中,我们将选择1000个随机节点作为“警察局”。

要找到每个节点距最近的派出所的距离,我能够通过实现多源BFS来解决该问题,在该处,派出所节点首先添加到队列中。那么,在正常的BFS V时间运行时,复杂度为O(V + E),而O(V(V + E))则为

但是,我想不出一种方法来修改此算法,以找到每个节点到k个最近警察局的距离,而不仅仅是最近的一个。

如果你们能提出合适的算法或指出正确的方向,我将非常感谢!

2 个答案:

答案 0 :(得分:5)

我们可以运行BFS P次,每个派出所一次。 我们可以为每个顶点维护一个大小为k的堆,以保持k个距该顶点最近的警察局距离。

时间复杂度将为O(P(V + E)+ PVlogK)。

要使其速度更快,我们可以并行运行P BFS,以将时间最多减少C倍,其中C是机器中处理器核心的数量。

另一种优化方法是将顶点与所有警察局之间的距离存储在列表中,而不是堆中。 然后,我们可以使用计数排序并获得最近的k个工作站。 这部分的复杂性将从O(VPlogK)变为O(VP)。

答案 1 :(得分:3)

调整算法,以便在找到最近的警察局后继续执行。

IE:将警察局添加到列表中并继续。将其视为正常节点。仅在找到K个警察局后才停止。

看看Wikipedia for BFS,我们发现以下一般算法:

process_txt

要允许我们搜索警察局,我们只需添加一些步骤:

  1. 第3行之后,除了一个队列和一个Set(尽管还有其他方法,即IE:用于编号节点的布尔数组)来存储发现的节点之外,我们还需要一个Set来存储发现的警察局。
  2. 删除第7行和第8行。我们不再具有要在节点方面寻求的特定目标。
  3. 在第10行之后添加:如果 1 procedure BFS(G, root) is 2 let Q be a queue 3 label root as discovered 4 Q.enqueue(root) 5 while Q is not empty do 6 v := Q.dequeue() 7 if v is the goal then 8 return v 9 for all edges from v to w in G.adjacentEdges(v) do 10 if w is not labeled as discovered then 11 label w as discovered 12 Q.enqueue(w) 是警察局,则添加到w。如果police station discovered set的新大小为police stations discovered set,则返回K

哦,对,您需要距离,因此在将警察局添加到发现的集合中时,还要将距离添加到警察局距离列表中(这是在算法开始时必须添加的数组也是如此)。

相关问题