【问题标题】:Why is the BigO of adjacency list for a graph is (V + E) and not (V^2)?为什么图的邻接表 BigO 是 (V + E) 而不是 (V^2)?
【发布时间】:2016-12-10 16:42:34
【问题描述】:

如果我的想法是错误的,请纠正我。我认为 BigO(V + E) = BigO(V^2)。

以下是我的想法:
完整图中的边 = n*(n-1)/2。

从 E 和 V 切换到 n,因为这样想更容易。

E = n*(n-1)/2
V = n

BigO(V + E) => BigO(n + n*(n-1)/2) => BigO(n^2)

将 n 切换回 V。

=> BigO(v^2)

我错过了什么吗?为什么使用 BigO(V + E)?为什么不使用 BigO(V^2)?

【问题讨论】:

  • |E| = |V|*(|V|-1) / 2 仅当图是一个团时。如果不是派系那么|E|
  • 没有。 O(V^2) 忽略了这样一个事实,即对于 V 的固定值,函数随着 E 的增加而增长。这不是“最坏情况”的问题,因为最坏的情况是算法在输入上的表现与另一个相比最差相同大小的输入。
  • @beaker 你能解释一下为什么最坏的情况在这里不适用吗?边的输入可以变化,不是吗?
  • 是的,该评论现在有点断章取义,因为它最初是为响应现已删除的答案而编写的。我的意思是你不能说“复杂性是 O(V^2),因为在最坏的情况下会有 O(V^2) 边缘。”改变边的数量会改变输入的大小。因此,这不是“最坏情况”,它只是在更大的数据集上的相同情况。
  • 顺便说一句,您可以在一般图中拥有多条边,因此如果“完整”图中的每个 (A,B) 都有 V 条边,则 E = V*V*(V-1 )/2。或者在最小连接树中(不确定什么是正确的英语术语,在我的语言中我们称之为一个“骨架”:))E 只是 V-1。 (我的错误:哦……当然,邻接表最多仍然是 V*(V-1)/2,除非你还考虑边缘的方向,或者其他一些人为的额外约束)

标签: data-structures graph big-o adjacency-list space-complexity


【解决方案1】:

邻接表的内存使用量与节点数和边数之和成正比。这是因为每个节点都有一个离开它的边的关联列表,并且每条边最多出现两次(对于它在无向图中接触的每个节点一次,或者对于有向图一次)。这意味着空间使用量是Θ(V + E)。

您对内存使用量给出了两个不同的渐近界限,O(V + E) 和 O(V2)。这两个界限都是正确的,但一个比另一个更紧。 O(V + E) 界更准确地表明有两个半独立的量进入空间使用,节点数和边数,并且更精确。 O(V2) 界限不太精确,但通过考虑以 V 表示的 E 的最大可能值,给出了总内存使用量的最坏情况界限。换句话说,O(如果您试图精确控制内存使用情况,V + E) 界限会更有用,但如果您担心最坏情况的内存,O(V2) 界限会更好用法。

(快速说明:“邻接表是 O(V + E)”这句话没有意义。由于 big-O 量化了函数的增长率,所以就像说“邻接表是 95,201 " - 这是没有意义的,因为您正在将一个对象与一个数字进行比较。但是,您可以说“邻接表的空间使用量是 O(V + E)”,因为邻接表的空间使用量是一个实际的数字量。 )

【讨论】:

    【解决方案2】:

    BigO 用于根据输入大小估算您将使用多少 <time, memory, whatever resource>

    当您构建邻接列表时,您会知道顶点数 V 和边数 E。现在你想估计你需要多少内存。

    O(V+E) 可以解释为V > E ? O(V) : O(E) 什么意思:它对max(V,E) 是线性复数。

    您为每个 v 创建一个列表,因此您在其上使用 O(V) 内存。 您标记每个边缘,这将使用 O(E) 内存。 O(V+E) 就是这个意思。如果您说复杂度是O(V^2),这意味着对于带有2*n 顶点的空图,您应该使用大约。 4 的内存比带有n 顶点的空图多。

    在对复杂性进行一些研究时,您可以测试不同的方法:

    • 最坏的情况,
    • 平均情况,
    • 最好的情况。

    如果您希望获得更多信息,请阅读有关该主题的不同方法并发表评论。

    编辑

    根据正式定义,O(V+E)O(V^2)O(V^3)O(V^V^V) 仍然是正确的。在BigO 中,我们尝试找到增长最慢但仍然是BigO 的函数。

    【讨论】:

      【解决方案3】:

      这两种说法都是正确的。它们并不矛盾。

      在任意图上,资源使用量为 O(V2)。但是在可能出现稀疏图的问题域中,资源使用量是 O(V+E)。这提供了更多信息。

      邻接表通常用于图可能稀疏的问题领域。对于密集图,数组通常是更好的解决方案。如果您正在考虑两种可能的算法来解决图问题,则需要考虑您对图的了解。出度是否受到限制?在这种情况下,邻接表表示和相关算法可能是更好的解决方案。

      复杂性分析不仅仅是一个理论游戏。这是一种组织您思考实际编程问题的实用解决方案的方法。

      【讨论】:

      • 随着图形变得越来越密集,E 接近 V^2。我会说你称之为 O(V^2) 而不是更严格的 O(V + E) 上限,你什么也得不到。
      • @beaker:如果您对图表一无所知,并且想与基于数组的算法进行比较,O(V²) 会更简单。有时,能够根据单个变量进行分析很有用。但无论如何。
      猜你喜欢
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 2015-01-01
      • 1970-01-01
      • 2017-01-08
      • 2018-12-18
      • 1970-01-01
      相关资源
      最近更新 更多