我的问题是docker-compose.yml
。
基本上,如果O(V+E) = O(V^2)
是线性时间O(V+E)
,那么V+E = n
也不是线性时间吗?
我假设O(V^2)
的最坏情况/上限是每个顶点之间的边缘,这将导致O(V+E)
边缘。我还假设可以将其视为(V-1)^2
,因此我认为这相当于V^2
。
答案 0 :(得分:4)
任何O(V + E)的运行时间也是O(V 2 ),因为您明确表达了(E = O(V 2 ))。这并不意味着说运行时为O(V 2 )是个好主意,因为这是一个不太精确的界限。在稀疏图中,O(V + E)比O(V 2 )更紧密。
然而,反过来却不是这样。例如,考虑这个算法:
for each node v in V:
for each node u in V:
print (v, u)
此算法的运行时间为Θ(V 2 ),其运行时间不依赖于图中的边数。因此,说运行时为O(V + E)是不正确的,因为在具有较少边数(例如树)的图中,O(V + E)的界限将错误地预测运行时节点数是线性的,而O(V 2 )的运行时间会以二次方正确地上限运行时。
答案 1 :(得分:1)
如果要为任何可以完全随机化的图形调整大小,那么可以根据节点数计算最大边缘。
你通常会看到独立计算E和V的原因是现实。实际上,完整的图表并不常见。即使理论上你可以说你有N个节点的图形,节点的平均边缘是一些常数,即10。
例如,如果您想找到最快的路径,可以为此实现Dijsktra。如果你使用真实的道路,你映射整个世界,将有很多顶点,其中大部分将限制为4个边缘(每个顶点是十字路口,通常你有4个选项),将有更多的他们,但不多,甚至那些都是有限的(你可以从一个十字路口只有有限数量的道路)。
因此,如果增加图形的大小(顶点)不会增加节点的平均边数,则需要独立计算E和V的信息。
例如,现实世界中的Dijkstra具有线性复杂性。但是对任何图形使用Dijsktra都可能具有高达V ^ 2的复杂度。但是如果你制作的程序在现实生活中找到了一些东西,你需要知道复杂性是线性的。
答案 2 :(得分:1)
否,O (|V| + |E|)
不等同于O (|V|^2)
。
这就是原因。
基本上,如果O(V + E)是线性时间使得V + E = n,那么O(V ^ 2)也是线性时间吗?
也许这假设图形以某种方式明确给出,我们必须将其作为输入接收才能使用它,并且边的总输入大小为O (|V| + |E|) = n
。
但我们不必总是接收输入一次,然后运行一次算法。 在某些情况下,我们会收到输入图,然后多次运行算法,因此无论输入大小如何,我们都对其复杂性感兴趣。 在其他一些情况下,图形是隐式给出的,因此输入不会花费太多时间。
示例:考虑k * k
棋盘上的knight's graph:顶点是棋盘方块的图形和边缘是骑士的移动。
要解决的一个示例问题是:给定两个方格,找到它们之间的骑士路径,其移动次数最短。
一个明显的解决问题的算法是breadth-first search,花费O (|V| + |E|)
时间
(我们可以做得更好但除此之外还有。)
此处,输入的大小为O (1)
:它只是棋盘的大小k
,以及其上两个方格的坐标。
我们不必在任何时候阅读或显式构建图形:它由大小k
隐式给出。
在每个顶点中,我们可以枚举O (1)
中此顶点的所有(最多8个)边。
就k
,|V| = O (k)
,|E| <= 8 k
所以|E| = O (k)
而言,我们也有O (|V| + |E|) = O (k)
。
另一方面,O (|V|^2) = O (k^2)
比O (k)
更宽松。
因此,在此示例中,O (|V| + |E|)
与O (|V|^2)
的不同,因此它们通常不相同。
答案 3 :(得分:0)
否强>
我假设O(V + E)的最坏情况/上限是每个顶点之间的边缘,这将导致(V-1)^ 2个边缘。
除非您的输入明确限于simple graph,否则任何非简单图形都可以有多条边连接顶点对和连接到单个顶点的循环边。
想象一下,在一个小镇周围连接环形交叉路口的道路系统非常简单:
因此,即使对于这个简化的现实世界示例,图表也不简单,并且有多边和循环边,如果O(|E|) = O(|V|³)
则O(|V|+|E|) > O(|V|²)
。