我是一名从未正式学过算法的程序员,并且一直想在我的学习中填补这个空白。我目前正在研究一些书籍和在线资料,我从概念上理解Big O,即它的用途,以及不同的性能类别,例如:常数,线性,二次等。我可以编码问题并直观地理解不同方法的性能影响。
然而,我一直坚持的是表示算法证明的表示法,而且我不知道在哪里看这个部分。我看过的所有书籍都具备这种知识水平。
例如,Skiena的算法设计手册中的这句话让我难过:
f(n)= O(g(n))表示c * g(n)是f(n)的上限。 < /强>
因此存在一些常数c使得f(n)总是≤c * g(n),足够大的n(即对于某些常数n≥n0) N0)。
这是读者应该完成的必然练习:
3n ^ 2 - 100n + 6 = O(n ^ 2),因为我选择c = 3且3n ^ 2> 3n ^ 2- 100n + 6;
我可以理解这两个陈述,并且逻辑上可以看到第二个陈述是正确的。我也理解上限的概念,即这是最坏的情况。
但我仍然坚持简单的事情,如上所述是什么?
g(n)
n≥n0为某些常数n0
总的来说,我不能把各个部分放在一起来理解整个证明。
任何人都可以帮助我用简单的英语解析上述陈述,并以对非技术人员有意义的方式展示它们与练习的关系
答案 0 :(得分:1)
我希望你仍然可以使用答案:)。
g(n)是您要比较 f(n)的函数,它是真正的运行时。例如,你会说冒泡排序 O(n ^ 2),使 g(n)= n ^ 2 。但是,直观地说,你的算法不会精确地 n ^ 2 时间单位(无论你想在这里插入什么时间单位);然而,它可能需要 3n ^ 2 - 100n + 6 (这是 f(n))时间单位。
现在,Big-Oh符号的作用是比较两个函数的增长速度;这是一个非常粗略比较,请注意。例如,它不区分需要 f(n)= n ^ 2 时间单位的算法与其他需要 f(n)= 5n ^ 2 的算法,也不区分区分 f(n)= n ^ 2 的 f(n)= n ^ 2 + n 。这是 c 发挥作用的地方 - 如果您能找到任何常数 c ,您可以将 g(n)与其相乘,以便对于每个 n ,结果函数返回的值大于 f(n),然后 f(n)= O(g(n))。
Big-Oh表示法所看到的是 f(n)中发展最快的部分。假设您想将 f(n)= n + 100 与 g(n)= n 进行比较。直观地, f(n)= O(g(n)),但是没有 c 你可以将 g(n)乘以这样它总是大于 f(n);然而, n 显然比 100 增长更快,而 100 根本没有增长。最后, n0 开始发挥作用:如果 n 的有限数量,那么Big-Oh符号会“容忍”它s, c * g(n)不大于 f(n),只要它对于无限数<更大<强>名词强>的。这个有限数用 n0 给出。例如,对于所有 n&lt; 1 (这是一个有限的数量:恰好是数字0), f(n)= n + 100 可以大于 c * g(n)= c * n 只要所有其他 n (无限量:所有数字&gt; = 1 ,使 n0 = 1 ) f(n)更小。
答案 1 :(得分:0)
这里的主要问题是你不习惯数学中使用的习语。
让我们一句一句地说:
f(n)= O(g(n))表示c * g(n)是f(n)的上限。
普通英语:嘿,写 c * g(n)是f(n)的上限对我来说太多了,我将会使用从这里开始很多。从现在开始,每次我想说,我都会写 f(n)= O(g(n))。此外, f(n)和 g(n)只是函数,我不关心哪一个只要它们取一些整数 n 作为论据并返回一些实际价值。 c 只是一些常数,因此我做出的肯定是正确的。请记住,我没有说复杂性,关于 f 或关于 g ,我只是创建一个快捷方式来说 c * g(n)是f(n)上限。
因此存在一些常数c使得f(n)总是≤c* g(n),足够大的n(即对于某些常数n0,n≥n0)。
普通英语:万一你不知道,我会记得你的功能上限是什么。 函数 g(n)是 f(n) 的上限,如果你能找到一个常量(我们称之为 c )使得足够大的n 的f(n)≤c* g(n)。你肯定想知道足够大意味着什么,是吗?我们只是说f(n)≤c* g(n)对于大于某个数的所有 n 都必须为真。我们不知道它是哪个号码而且我们不在乎知道,因为对我们来说唯一重要的是这个号码存在!我们将其称为 n0 ,以便我们可以说 n 足够大,如果n≥n0。
3n ^ 2 - 100n + 6 = O(n ^ 2),因为我选择c = 3且3n ^ 2> 3n ^ 2- 100n + 6;
普通英语:现在让我们尝试一个例子来展示它的工作原理。当我写 3n ^ 2 - 100n + 6 = O(n ^ 2)时,我们得到f(n)= 3n ^ 2 - 100n + 6和g(n)= n ^ 2。看看我在那里做了什么?事实上,我之前没有说出 f(n)和 g(n)是什么让我放任何函数。
正如你所看到的,我在这里的意思是短语c * n ^ 2是3n ^ 2 - 100n + 6的上界。这是一个可以是真或假的肯定。上限的定义将让我们知道如何判断它是否为真。证明确认为真的一种方法是找到一些数字 c 和一些数字 n0 ,使得3n ^ 2 - 100n +6≤c* n ^ 2,所有n≥n0。如果我们尝试c = 3,我们必须证明对于所有n> 3n ^ 2 - 100n +6≤3* n ^ 2。 n0,这相当于证明-100n +6≤0,对于某些n> 1。 N0。最后我们可以说,为了它是真的,我们需要n0≥6/ 100。我们找到了我们的n0,我们已经证明了整个肯定是真的
我认为你的问题是你希望事情具体化。另一方面的数学试图是抽象的。这就是为什么它提到函数 f 和 g 而不说它们实际上是什么。您只需要知道它们是函数,并且作为函数它们具有某些属性。这个想法是你想要推理函数的属性而不是一些具体的函数。同样的事情对于 n0 是有效的,你只关心它的存在,而不关心它的价值。如果存在,您可以将其考虑在您的推理中。
我希望我的回答对你有帮助。