Algorithm 我的函数是O(n!),还是O((n-1)!)更精确?
我已经为旅行推销员问题编写了一个蛮力搜索算法,并对其进行了测试,以查看不同数量的“城市”所需的时间。从下图中,我们可以看到时间大致与Algorithm 我的函数是O(n!),还是O((n-1)!)更精确?,algorithm,time-complexity,big-o,Algorithm,Time Complexity,Big O,我已经为旅行推销员问题编写了一个蛮力搜索算法,并对其进行了测试,以查看不同数量的“城市”所需的时间。从下图中,我们可以看到时间大致与(n-1)成正比其中n是“城市”的数量。它与n不成正比(毕竟,(n-1)!=n!/n) 我的问题是,说算法在O(n!)中运行还是说O((n-1)!)更好?我以前从未见过后者,但它似乎更准确。我好像误解了什么 [t=所用时间,n=城市数量]O(n!)就足够了n或n-1对大型n没有影响 看 例如 根据定义,O(f(n))是由f(n)渐近支配的所有函数的集合,即所有函数
(n-1)成正比代码>其中n
是“城市”的数量。它与n不成正比代码>(毕竟,(n-1)!=n!/n
)
我的问题是,说算法在O(n!)
中运行还是说O((n-1)!)
更好?我以前从未见过后者,但它似乎更准确。我好像误解了什么
[t=所用时间,n=城市数量]O(n!)
就足够了n
或n-1
对大型n
没有影响
看
例如 根据定义,O(f(n))是由f(n)渐近支配的所有函数的集合,即所有函数g(n)的集合,其中有常数C和n_0,使得
g(n) < C * f(n) for all n > n_0
g(n)n\u 0
根据这个定义,O(n!)实际上是O((n-1)!)的超集,因为函数f(n)=n!是第一个集合的成员,但不是第二个集合的成员。这两套实际上并不相同
不过,说你的问题是O(n!)是正确的,因为这只说明了一个上边界。说你的问题是ϴ(n!)是不正确的,因为这表示常数因子的精确渐近行为
实践中没有大的区别,正如另一个答案所指出的,你可以重新定义n,表示城市数量减去1。你可以简单地证明如下:
O((n-1)!)表示存在常数c,例如:
算法步骤(或时间复杂度)1
因此,由于for complexity函数的算法保持不变:
算法步骤(或时间复杂度)
你的算法也是O(n!)
因此,我们证明了如果算法的时间复杂度是O((n-1)!),那么它也是O(n!)。Sven Marnach的答案非常好,我只想在这一部分详细说明一下:
还是我说O((n-1)!)更好
正如其他人所说,O(n)
通常已经足够好了。如果您确实想了解有关问题的更多信息,您可以尝试查找并证明:
- 下限(通常用
Ω(n)
表示)
- 严格的上限
下界基本上是说,在某些假设下,不可能有算法渐近更快地解决问题。紧上界是与下界匹配的上界,即,必须证明Ω(f(n))
的下界和O(f(n))
的上界。如果你能证明一个下界和一个紧上界,这意味着你的算法是这个问题的渐近最优算法
举一个具体的例子:你肯定知道像merge-sort或quick-sort这样的排序算法,以及它们的上界O(n logn))
。Donald Knuth(几十年前)指出,基于比较的整数排序算法至少需要n logn
比较,即Ω(n logn)
操作。因为我们有一个匹配的上界,合并排序和快速排序都被认为是渐近最优的(尽管它们的性能在实践中有很大的不同)。比如,一个大值是n=100
,然后O(n!)=9.33*10^157
,其中O((n-1)!=9.33*10^155
。你认为这两者之间没有区别吗??)它们都是“大得像地狱一样,无论如何都不能用于大n”。所以,事实上没有区别:)这两个数字都比宇宙中估计的原子数(仅为10^81)还要大。@jbsu32,这简直是胡说八道O(…)
是一类函数,不能等于数字。是的,O(10n)=O(n)
,所以对于O
-符号,O(f(n))
是一类函数,类似于偶数或可微函数,在3990万
和360万
之间没有区别。@jbsu32,O(f(n))
是一类函数。斯文(或在数学书中)解释了这门课的具体内容。如果我们把类看作是属于这个类的所有函数的集合(共同概念),那么是的,O(10n)=O(n)=O(10^100n)
,因为它们的元素是相同的。@jbsu32,O(10n)总是等于O(n),因为我们不关心常数因子这个答案使用了正确的方法。事实上,人们通常有O(f(n))=O(f(n-1))
——例如,如果f
是多项式或指数,这是正确的。然而,如上所述,并非所有函数都是如此:我们有limn/(n-1)!=lim n=infty
表示n->infty
。对。我不太同意f(n)
和f(n-1)
之间的“在实践中没有大的区别”——当函数的增长速度和阶乘一样快的时候就不行了!这样,可以说任何Θ(n!)算法只适用于非常小的输入;你永远不会有机会把n
做得太大,以至于一个或多或少都是无关紧要的。“你可以重新定义n来表示城市数量减去一。”这是一个坏主意,因为这会导致混乱。为什么不把它定义为sqrt(| cities |)?Big-O符号的可能重复并不是为了实际提供算法的计算,而是为了提供它们之间的抽象比较方法。算法的最终行为是阶乘-它恰好是+1或-1这一事实无关紧要。