【问题标题】:Time complexity for Dijkstra's algorithm with min heap and optimizations具有最小堆和优化的 Dijkstra 算法的时间复杂度
【发布时间】:2022-01-22 14:49:01
【问题描述】:

Dijkstra 算法的这个特定实现的时间复杂度是多少?

当你使用最小堆时,我知道this question 的几个答案,比如 O(E log V),this articlethis article 也是如此。但是,article here 表示 O(V+ElogE),它的逻辑与下面的代码相似(但不完全相同)。

算法的不同实现可以改变时间复杂度。我正在尝试分析下面实现的复杂性,但是检查visitedSet 和忽略minHeap 中的重复顶点等优化让我怀疑自己。

这是伪代码:

// this part is O(V)
for each vertex in graph {
  distanceMap[vertex] = infinity
}

// initialize source vertex
minHeap.add(source vertex and 0 distance)
distanceMap[source] = 0
visitedSet.add(source vertex)

// loop through vertices: O(V)?
while (minHeap is not empty) {

  // Removing from heap is O(log n) but is n the V or E?
  vertex and distance = minHeap.removeMin
  if (distance > saved distance in distanceMap) continue while loop

  visitedSet.add(vertex)

  // looping through edges: O(E) ?
  for (each neighbor of vertex) {
    if (visitedSet contains neighbor) continue for loop

    totalDistance = distance + weight to neighbor
    if (totalDistance < saved distance in vertexMap) {

      // Adding to heap is O(log n) but is n the V or E?
      minHeap.add(neighbor and totalDistance)
      distanceMap[neighbor] = totalDistance
    }
  }
}

注意事项:

  • 从源顶点可到达的每个顶点将至少被访问一次。
  • 检查每个顶点的每条边(邻居),但如果在visitedSet 中则忽略
  • 仅当邻居的距离小于当前已知距离时,才会将邻居添加到堆中。 (假设未知距离的默认长度为无穷大。)

这个实现的实际时间复杂度是多少?为什么?

【问题讨论】:

  • 只是为了确定:不会对这个伪代码进行任何更改,而且您也不想优化它,对吧?
  • 正如您在代码中提到的,minHeap 存储的距离是边的权重,但是,这些权重的数量最多是顶点的数量。因此,while 循环最多迭代 O(v) 次,添加到堆或从堆中删除将是 O(log(v))。此外,我认为循环一个顶点的邻居也是 O(v) 而不是 O(E),因为特定顶点最多有 v-1 个邻居。
  • 没有执行 O(E + log V) 的 dijkstra 算法。其中大多数是 O(E * log V)。我访问了您的参考资料link,但它表明时间复杂度为 O(E * log V)。
  • @trincot,是的,没错。
  • @CodePlus,感谢您发现我的错误。我已经更新了问题。

标签: algorithm graph time-complexity big-o dijkstra


【解决方案1】:
  1. 尽管进行了测试,但 Dijkstra 的这种实现可能会将 Ω(E) 项放入优先级队列中。对于每个基于比较的优先级队列,这将花费 Ω(E log E)。

  2. 为什么不是 E log V?好吧,假设一个连通的、简单的、非平凡的图,我们有 Θ(E log V) = Θ(E log E) 因为 log (V−1) ≤ log E

  3. Dijkstra 算法的 O(E + V log V) 时间实现依赖于(n 摊销的)恒定时间 DecreaseKey 操作,避免单个顶点的多个条目。然而,在稀疏图上,这个问题的实现可能会更快。

【讨论】:

  • 问题 1:关于第 1 点,您使用 Ω(E log E)。我的理解是 Ω 是下限,O 是上限,而 Θ 是严格或精确的界限。这是否意味着我不能说 O(E log E) 因为没有这样的上限?
  • 问题 2:既然我通过访问每个顶点来启动算法,那不是将其更改为 Ω(V + E log E) 吗?还是 V 抵消了,因为可以假设 V
  • 对于此答案的其他读者,以下是我在尝试理解它时发现有用的一些链接:O vs Ω vs ΘDecreaseKey
  • @Suragch 1. 如果您使用低效队列,则可能是 Theta(E^2) 或更糟。 2. 这是在这里使用 Omega 的另一个原因,尽管我特别引用了队列操作的成本。是的,从技术上讲,算法的整体运行时间通常必须包含一个 V,但如果 V-1 ≤ E(例如,连通图),那么我们可以将 V 折叠成 E log E 或 E log V。跨度>
猜你喜欢
  • 2020-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
  • 1970-01-01
  • 2014-12-20
  • 2019-05-14
  • 2011-07-25
相关资源
最近更新 更多