@
laxenade @
rogerchen 首先对于“民间科学家”的不当言论表示歉意。但是我仍然有话反驳。
先列出结论:我认为就你们举的这个例子,无论是 O(n) 还是 O(n log2 n) 都是逻辑自洽的,其中 O(n log2 n) 的论述见我之前的回复。当令 k = log2(n),可得 O(2^k * k)。然而在这里如果我想要把 k 代换成 n 给出 O(2^n * n) 的复杂度就是不恰当的,因为 n 在上下文是有明确含义的,不能把一个符号随意变换含义。
所以对于 O(2^n) 的这个结论,如果按照 n 表示 k 的角度去看,就少了一个 *k 的因子;如果不是这样,那就显然更加离谱了。
- - - -
@
rogerchen 对于你说的复杂度分析不应该考虑工程问题,这显然不合适。我们目前的算法都是为了电子计算机设计的,因此所有算法分析和时间复杂度估计都是在电子计算机的前提下成立的;这已经考虑了工程问题。
@
laxenade 你说“限制 32bit 的话,那就都变成 O(1)了”,只是大 O 。就算是考虑 32 位整数,在这个例子里面,当限定 n 为 32 位整数, O(15 n) (见我先前的回复)依旧是比 O(15 * 2^32) 更紧的界。同时,算法的复杂度不会小于 Ω(n)。因此 Ω(n) 和 O(15 n) 卡住了这个算法在 32 位整数下的界,因此 Θ(n) 是紧界。
当然如果按照教科书的定义,一切 n < ∞ 的论述都是没有意义的。可是啊,读书不能死扣概念,要领会它的精神。复杂度分析是为了在没有测试算法的前提下估计它的运行时间,当我们有了 32 位整数的大前提下,考虑更细致的界依旧是有意义的,因为我们可以通过计算来估计两个不同算法的优劣。
- - - -
@
rogerchen @
laxenade 另外还有第二点反驳。你们可能不赞同我说的,“可以定义 i++, sum++, i<n 三个操作为常数时间”。然而你们是出于电子计算机的前提才这么反驳我的。我们谁也不知道将来的量子计算机,乃至什么其他种类的计算机究竟能够有多快,因此我假设这三个操作是 O(1) 是公理,完全不违背理论性。
如果接受这三个假设,那么你们的算法复杂度是 O(n) 是没有错误的结论。当然如果不接受,认为这三个操作的复杂度是 O(log2 n),那么推出来的结论就是 O(n log2 n)。
当我们考虑 32 位定长整数的电子计算机的时候,也可以认为上述三个操作为 O(1),得出 O(n) 的结论。