是否有O(1 / n)算法?

还是其他小于O(1)的算法?

评论

大多数问题都假设您的意思是“是否存在时间复杂度为O(1 / n)的算法?”我们可以假设是这种情况吗? Big-O(和Big-Theta等)描述函数,而不是算法。 (我不知道函数和算法之间是否等效。)

这是计算机科学中“ O(X)算法”的普遍理解的定义:一种算法,其时间复杂度为O(X)(对于某些表达式X)。

在使用缓冲树的I / O有效优先级队列算法的情况下,我听说过这样的限制。在缓冲树中,每个操作占用O(1 / B)个I / O。其中B是块大小。 n次操作的总I / O为O(n / B.log(base M / B)(n / B)),其中log部分是缓冲树的高度。

有很多算法具有O(1 / n)错误概率。例如,带有O(n log n)个存储桶的Bloom过滤器。

您不能通过添加鸡来更快地产卵。

#1 楼

这个问题并不像看起来那样愚蠢。至少从理论上讲,当我们采用Big O符号的数学定义时,诸如O(1 / n)之类的东西是完全明智的:



现在您可以轻松替换g(x)表示1 / x…显然,上述定义对于f也成立。随着输入的增长更快。当然,您可以构造一个任意算法来实现此目标,例如以下代码:

 def get_faster(list):
    how_long = (1 / len(list)) * 100000
    sleep(how_long)
 


很显然,随着输入大小的增加,此函数花费的时间更少…至少直到某个限制,由硬件强制执行(数字的精确度,sleep可以等待的最短时间,处理参数的时间等):那么该限制将是一个恒定的下限,因此实际上上述功能仍然具有运行时O(1)。

但是实际上,在现实世界中,当输入大小增加时,运行时可以减少(至少部分减少)的算法。请注意,这些算法在O(1)以下不会表现出运行时行为。仍然,它们很有趣。例如,采用Horspool的非常简单的文本搜索算法。在这里,预期的运行时间将随着搜索模式长度的增加而减少(但是,增加干草堆的长度将再次增加运行时间)。

评论


“由硬件执行”也适用于图灵机。在O(1 / n)的情况下,总会有一个输入大小,该算法不应对其执行任何操作。因此,我认为O(1 / n)的时间复杂度确实是不可能实现的。

–罗兰·埃瓦尔德(Roland Ewald)
09年5月25日在14:10

梅尔达德,你不明白。 O符号是关于极限(技术上为lim sup)的n->∞。算法/程序的运行时间是某台机器上的步骤数,因此是离散的-算法可以花费的时间(“一步”)下限为非零。程序可能会达到某个有限的N数,且步数随着n的减少而减小,但是算法的唯一方法是O(1 / n)或实际上是o(1),如果所有时间都花费了时间0大n-这是不可能的。

–ShreevatsaR
09年5月25日在20:04

我们不同意存在O(1 / n)函数(在数学意义上)。显然他们做到了。但是计算本质上是离散的。在von Neumann体系结构或纯抽象的Turing机器上,诸如程序运行时间之类的下限不能为O(1 / n)。等效地,O(1 / n)不能具有下限。 (您必须调用“睡眠”功能,或者必须检查变量“列表”,或者必须在图灵机上检查输入磁带。因此,所花费的时间将随着n的变化而变化,其中ε+ 1 // n,不是O(1 / n))

–ShreevatsaR
09年5月26日在0:14

如果T(0)=∞,它不会停止。没有“ T(0)=∞,但仍然停止”之类的东西。此外,即使您在R∪{∞}中工作并定义T(0)=∞,并且T(n + 1)= T(n)/ 2,对于所有n而言,T(n)=∞。让我重复一遍:如果一个离散值函数是O(1 / n),那么对于所有足够大的n,它都是0。[证明:T(n)= O(1 / n)表示存在一个常数c使得对于n> N0,T(n) max(N0,1 / c),T(n)<1,这意味着T(n)= 0。]任何机器,无论是真实的还是抽象的,都不会花费0时间:它必须查看输入。好吧,除了永远不做任何事情的机器,并且对于所有n而言,T(n)= 0。

–ShreevatsaR
09年5月27日,3:50

您必须喜欢任何开头为“这个问题并不像看起来那样愚蠢”的答案。

– Telemachus
09年6月27日在12:53

#2 楼

是。

有一种运行时为O(1 / n)的算法,即“空”算法。

将算法设为O(1 / n)意味着它与由一条指令组成的算法相比,以更少的步骤渐近执行。如果所有n> n0的执行步数少于一个步骤,则对于所有n,它必须完全不包含任何指令。由于检查“如果n> n0”至少要花费1条指令,因此它必须不包含所有n条指令。

总结:
唯一的算法是O(1 / n)是空算法,不包含任何指令。

评论


因此,如果有人问空算法的时间复杂度是多少,您会回答O(1 / n)?我莫名其妙地对此表示怀疑。

– phkahler
2010-2-16在20:42

这是该线程中唯一的正确答案,并且(尽管我赞成)它的票数为零。这就是StackOverflow,其中“看起来正确”的答案被投票高于实际正确答案。

–ShreevatsaR
2010-2-24在17:15

否,因为它是错误的,它的等级为0。当它独立于N时,相对于N表示big-Oh值是错误的。其次,运行任何程序,即使是刚刚存在的程序,也至少要花费恒定的时间O(1)。即使不是这种情况,也应该是O(0),而不是O(1 / n)。

– kenj0418
2010-2-28在17:16

O(0)的任何函数也是O(1 / n),也是O(n),也是O(n ^ 2),也是O(2 ^ n)。 igh,没有人能理解简单的定义吗? O()是一个上限。

–ShreevatsaR
2010-4-15的3:52

@ kenj0418您在每个句子中都设法弄错了。 “当与N无关时,相对于N表示big-Oh值是错误的。”常数函数是完美的傻瓜函数。 “第二,运行任何程序,甚至只是一个已经存在的程序,都至少需要固定的时间O(1)。”复杂性的定义并没有说明实际运行任何程序。 “它将是O(0),而不是O(1 / n)”。参见@ShreevatsaR的评论。

–阿列克谢·罗曼诺夫(Alexey Romanov)
10年8月24日在20:12

#3 楼

Sharptooth是正确的,O(1)是可能的最佳性能。但是,这并不意味着快速的解决方案,而仅是固定时间的解决方案。

一个有趣的变体,也许是真正的建议,是随着人口的增长,问题变得更加容易。我可以想到1,尽管人为地作弊,但答案是:

组合中的任何两个人的生日相同吗?当n超过365时,返回true。尽管小于365,但这是O(n ln n)。也许不是一个很好的答案,因为这个问题并没有慢慢变得容易解决,而是在n> 365时变成O(1)。

评论


366.不要忘记leap年!

–尼克·约翰逊(Nick Johnson)
09年5月25日在12:17

你是对的。像计算机一样,我有时也会遇到四舍五入的错误:-)

–阿德里安
09年5月26日在0:14

+1。随着n的增加,有许多NP完全问题会经历“相变”,即,当您超过n的某个阈值时,它们会变得容易得多或困难得多。一个例子是数字划分问题:给定一组n个非负整数,将它们划分为两部分,以使每部分的总和相等。在某个阈值n时,这变得非常容易。

– j_random_hacker
09年5月26日在11:34

#4 楼

那不可能Big-O的定义不小于不等式:

A(n) = O(B(n))
<=>
exists constants C and n0, C > 0, n0 > 0 such that
for all n > n0, A(n) <= C * B(n)


所以B(n)实际上是最大值,因此如果n随着增加而减小估计不会改变。

评论


我怀疑这个答案是“正确的答案”,但是不幸的是我缺乏理解它的智慧。

–自由空间
09年5月25日下午6:24

AFAIK此条件对于所有n都不必为真,而是对于所有n> n_0(即,仅当输入的大小达到特定阈值时)。

–罗兰·埃瓦尔德(Roland Ewald)
09年5月25日在7:37

我看不出定义(甚至更正)如何与OP问题矛盾。该定义适用于完全任意的功能! 1 / n是B的一个完全明智的函数,实际上,您的方程式与此并不矛盾(只需做数学运算即可)。因此,尽管有很多共识,但实际上,这个答案是错误的。抱歉。

–康拉德·鲁道夫(Konrad Rudolph)
09年5月25日在8:00

错误!我不喜欢不赞成投票,但您指出,如果没有明确的共识,这是不可能的。实际上,您是正确的,如果您确实以1 / n的运行时间构造函数(简单),它将最终达到最短的时间,从而在实现时有效地使其成为O(1)算法。虽然没有什么可以阻止该算法在纸上成为O(1 / n)。

– jheriko
09年5月25日在9:56

@Jason:是的,现在您说出来... :) @jheriko:O(1 / n)的时间复杂度在纸上恕我直言不起作用。我们正在表征图灵机的增长函数f(输入大小)= #ops。如果在x步之后它确实停止了长度为n = 1的输入,那么我将选择n >> x的输入大小,即足够大,如果算法确实为O(1 / n),则不应该进行任何运算完成。图灵机甚至应该如何注意到这一点(不允许从磁带读取一次)?

–罗兰·埃瓦尔德(Roland Ewald)
09年5月25日在13:54

#5 楼

根据我以前对大O表示法的了解,即使您需要第一步(例如检查变量,执行赋值),也就是O(1)。

请注意,O(1)是与O(6)相同,因为“常数”无关紧要。这就是为什么我们说O(n)与O(3n)相同。 ,算法可以执行的最小值为O(1)。除非我们不这样做,否则我认为它是O(0)?如果我们什么都不做,那么它就是O(1),这是它可以达到的最小值。

(如果我们选择不做,那么它可能会成为禅宗或道教问题。 ..在编程领域中,O(1)仍然是最小值)。

或者这样:

程序员:老板,我找到了一种方法老板:没必要做,今天早上我们破产了。程序员:哦,那变成了O(0)。

评论


您的笑话使我想起了编程之道:canonical.org/~kragen/tao-of-programming.html#book8(8.3)

– kenj0418
2010-2-28在17:06

由零步组成的算法为O(0)。那是一个非常懒惰的算法。

–nalply
2011年10月10日在20:41

#6 楼

不,这是不可能的:

由于n趋于1 / n的无穷大,我们最终会获得1 /(inf),实际上是0。

-oh类的问题是O(0),其n较大,但接近恒定时间的n较低。这是不明智的,因为唯一比固定时间快的事情是:

void nothing() {};

甚至这也是有争议的!

一旦执行命令,您就至少在O(1)中,所以不,我们不能有O(1 / n)的大对象!

#7 楼

根本不运行该功能(NOOP)怎么办?或使用固定值。这算吗?

评论


那仍然是O(1)运行时。

–康拉德·鲁道夫(Konrad Rudolph)
09年5月25日在8:10

对,那仍然是O(1)。我看不到有人怎么能理解这一点,但在另一个答案中却声称可能会发生比NO-OP少的事情。

–ShreevatsaR
09年5月25日在20:21

ShreevatsaR:绝对没有矛盾。您似乎无法理解大的O表示法与功能所花费的时间无关–而是描述了时间如何随着输入的变化(超过某个值)而变化。有关更多信息,请参见其他评论主题。

–康拉德·鲁道夫(Konrad Rudolph)
09年5月25日在20:42

我掌握得很好,谢谢。就像我在另一个线程中多次提到的那样,要点是,如果时间随着输入而减少,速率为O(1 / n),那么它最终必须减少到NOOP所花费的时间以下。这表明没有算法可以渐近地成为O(1 / n),尽管可以肯定的是它的运行时间可以减少到一个极限。

–ShreevatsaR
2010年7月9日在7:25

是的...就像我在其他地方说过的那样,任何O(1 / n)算法也应为所有输入花费零时间,因此取决于您是否认为null算法花费0时间,是否存在O(1 / n)算法。因此,如果您认为NOOP为O(1),则没有O(1 / n)算法。

–ShreevatsaR
2010年7月9日在16:51

#8 楼

我经常用O(1 / n)来描述随着输入变大而变小的概率-例如,公平硬币在log2(n)翻转时出现尾巴的概率是O(1 / n)。 />

评论


那不是什么大O。您不能只是重新定义它来回答问题。

– Zifre
09年5月25日在20:11

这不是重新定义,而是大O的定义。

–ShreevatsaR
09年5月25日在20:18

我是理论上的计算机科学家。它与函数的渐近阶有关。

–戴夫
09年5月25日在23:03

大O是任意实函数的一个属性。时间复杂度只是其可能的应用之一。空间复杂度(算法使用的工作内存量)是另一个问题。这个问题是关于O(1 / n)算法的,这意味着它是其中的一种(除非还有另一个适用于我不知道的算法)。其他应用包括人口增长顺序,例如在康威的生活中。另请参见en.wikipedia.org/wiki/Big_O_notation

– Stewart
09年8月17日在15:51

@戴夫:问题不是是否存在O(1 / n)函数,而这显然确实存在。而是是否存在O(1 / n)算法,该算法(可能存在null函数例外)不存在

– Casebash
2010年7月9日在10:58



#9 楼

O(1)的简单含义是“恒定时间”。

将早期退出添加到循环[1]时,您(将以O表示)将O(1)算法转换为O (n),但要使其更快。

诀窍通常是恒定时间算法是最好的,而线性算法则要好于指数算法,但是对于少量n而言,指数算法实际上可能是

1:假定此示例的列表长度为静态

#10 楼

对于阅读此问题并想了解对话内容的任何人,这可能会有所帮助:

|    |constant |logarithmic |linear|  N-log-N |quadratic|  cubic  |  exponential  |
|  n |  O(1)   | O(log n)   | O(n) |O(n log n)|  O(n^2) |  O(n^3) |     O(2^n)    |
|  1 |       1 |          1 |     1|         1|        1|       1 |             2 |
|  2 |       1 |          1 |     2|         2|        4|       8 |             4 |
|  4 |       1 |          2 |     4|         8|       16|      64 |            16 |
|  8 |       1 |          3 |     8|        24|       64|     512 |           256 |
| 16 |       1 |          4 |    16|        64|      256|   4,096 |         65536 |
| 32 |       1 |          5 |    32|       160|    1,024|  32,768 | 4,294,967,296 |
| 64 |       1 |          6 |    64|       384|    4,069| 262,144 |   1.8 x 10^19 |


#11 楼

我相信量子算法可以通过叠加“一次”执行多种计算...

我怀疑这是一个有用的答案。

评论


那仍然是恒定的时间,即O(1),这意味着运行大小为n的数据所需的时间与运行大小为1的数据所需的时间相同。

–自由空间
09年5月25日下午6:22

但是,如果问题是淡啤酒呢? (啊哈哈哈)

–杨杰夫·肉丸(Jeff Meatball Yang)
09年5月25日下午6:31

那将是一个超级位置。

–丹尼尔(Daniel Earwicker)
09年5月25日在7:27

量子算法可以执行多个计算,但是您只能检索一个计算的结果,而不能选择要获得的结果。值得庆幸的是,您还可以对整个量子寄存器进行操作(例如QFT),因此您更有可能找到某些东西:)

–Gracenotes
09年5月25日晚上8:02

它可能没有用,但是它具有真实性的优点,这使它在某些投票率较高的答案中脱颖而出B-)

–布莱恩·波斯托(Brian Postow)
2010年7月9日在19:20

#12 楼

许多人都有正确的答案(否)这是另一种证明方法:要拥有一个函数,您必须调用该函数,并且必须返回一个答案。这需要一定的恒定时间。即使对于较大的输入,其余处理花费的时间更少,打印出答案(我们可以假设为单个位)也至少需要恒定的时间。

#13 楼

如果存在解决方案,则可以在恒定的时间内立即准备并访问它。例如,如果您知道排序查询是针对逆序的,则使用LIFO数据结构。如果选择了适当的模型(LIFO),则数据已经被排序。

#14 楼

随着人口的增长,哪些问题变得更加容易?一个答案是类似bittorrent的事情,其中​​下载速度是节点数的反函数。与汽车相反,汽车加载得越慢,速度越慢,像bittorrent这样的文件共享网络会加快连接的节点的数量。

评论


是的,但是bittorrent节点的数量更像并行计算机中的处理器数量。在这种情况下,“ N”将是尝试下载文件的大小。就像如果有N台计算机,您可以在恒定时间内找到长度为N的未排序数组中的元素一样,如果有N台计算机尝试向您发送数据,则可以在恒定时间内下载大小为N的文件。

– Kibbee
2009年5月25日14:54

#15 楼

您不能低于O(1),但是可以使k小于N的O(k)。我们称它们为亚线性时间算法。在某些问题中,亚线性时间算法只能给出特定问题的近似解。但是,有时,近似解决方案就可以了,这可能是因为数据集太大,或者由于计算量太大而无法全部计算。

评论


不确定我是否理解。 Log(N)小于N。这是否意味着Log(N)是次线性算法?而且确实存在许多Log(N)算法。一个这样的例子是在二叉树中找到一个值。但是,它们仍然不同于1 / N,因为Log(N)始终在增加,而1 / n是减少的函数。

– Kibbee
2009年5月25日14:41

从定义上看,亚线性时间算法是指时间增长速度小于大小N的任何算法。因此,其中包括对数时间算法,即Log(N)。

–郝宇林
09年5月26日在2:08

嗯,亚线性时间算法可以给出准确的答案,例如在RAM机器上的有序数组中进行二进制搜索。

– A. Rex
09年5月28日在0:39

@一种。雷克斯:郝宇林说:“有一些问题”。

– LarsH
2010-09-29 5:41

#16 楼

怎么办:

void FindRandomInList(list l)
{
    while(1)
    {
        int rand = Random.next();
        if (l.contains(rand))
            return;
    }
}


随着列表大小的增加,程序的预期运行时间会减少。

评论


我认为您不了解O(n)的含义

–马库斯·劳斯伯格(Markus Lausberg)
09年5月25日下午6:40

但是不包含列表,包含contains为O(1)的数组或哈希

– vava
09年5月25日下午6:43

好的,可以将随机函数视为一个惰性数组,因此您基本上是在“惰性随机列表”中搜索每个元素,并检查其是否包含在输入列表中。我认为这比线性更糟糕,而不是更好。

–hasen
09年5月25日下午6:54

如果您注意到int的值集有限,那么他有一点意义。因此,当l包含2 64 值时,它将一直都是瞬时的。无论如何,这比O(1)还差:)

– vava
09年5月25日在7:01

#17 楼

O(1 / n)不小于O(1),这基本上意味着您拥有的数据越多,算法就越快。假设您得到一个数组,并且如果数组少于10100个,则始终最多填充10100个元素;如果数组更多,则不执行任何操作。当然这不是O(1 / n),而是O(-n):)太差的O-big表示法不允许负值。

评论


“ O(1 / n)不小于O(1)”-如果函数f为O(1 / n),则它也是O(1)。 big-oh感觉上很像是一个“小于”关系:它是自反的,是可传递的,并且如果我们在f和g之间具有对称性,则这两个等价关系是相等的,其中big-theta是我们的等价关系。但是,ISTR的“真实”排序关系要求a = b和b <= a表示a = b,而netcraft ^ W维基百科对此进行了确认。因此从某种意义上讲,可以公平地说O(1 / n)确实小于O(1)。

–乔纳斯·科尔克(JonasKölker)
09年5月26日在3:15

#18 楼

正如已经指出的那样,除了null函数的可能例外之外,不能存在O(1/n)函数,因为花费的时间将不得不接近0。

当然,有一些算法,例如由Konrad定义的值,至少在某种意义上似乎应该小于O(1)

def get_faster(list):
    how_long = 1/len(list)
    sleep(how_long)


如果要研究这些算法,则应该定义自己的渐近测量或自己的时间观念。例如,在上述算法中,我可以允许使用一定数量的“免费”操作。在上述算法中,如果我通过排除除睡眠以外的所有时间来定义t',则t'= 1 / n,即O(1 / n)。可能有更好的例子,因为渐近行为是微不足道的。实际上,我确信外面有人会产生非凡结果的感觉。

评论


“正如已经指出的那样,除了可能存在null函数的例外之外,不可能有O(1 / n)函数,因为所花费的时间必须接近0。”呃... 1 / n或1 /n²或1 /n³或...

– A.P.
20-10-16在19:58



#19 楼

其余大多数答案都将big-O解释为仅与算法的运行时间有关。但是由于问题没有提及,所以我认为值得一提的是big-O在数值分析中的另一种应用,它涉及误差。

许多算法可以是O(h ^ p)或O(n ^ {-p})取决于您是在讨论步长(h)还是除法数(n)。例如,在欧拉方法中,假设您知道y(0)和dy / dx(y的导数),则寻找y(h)的估计值。您对y(h)的估计越接近h,它的精度就越高。因此,为了找到某个任意x的y(x),将0到x的间隔取为零,将其拆分为n个片段,然后运行Euler方法在每个点上,从y(0)到y(x / n)到y(2x / n),依此类推。

所以Euler的方法就是O(h)或O (1 / n)算法,其中h通常被解释为步长,n被解释为除以间隔的次数。

您还可以将O(1 / h)实数数值分析应用中,由于存在浮点舍入误差。间隔越小,执行某些算法所产生的抵消就越多,有效位数的损失也就越大,因此通过算法传播的错误也就越多。

对于Euler方法,如果您使用浮点数,请使用足够小的步长并进行抵消,然后将一个小数加到一个大数上,而使大数保持不变。对于通过在两个非常接近的位置求值的函数彼此相减两个数来计算导数的算法,在平滑函数y中用(y(x + h)-y(x)/ h)近似y'(x) (x + h)接近y(x),从而导致较大的抵消,并且用较少的有效数字来估计导数。反过来,这将传播到您需要导数的任何算法(例如,边值问题)。

#20 楼

我想小于O(1)是不可能的。算法占用的任何时间称为O(1)。但是对于O(1 / n),下面的函数如何。 (我知道此解决方案中已经提供了许多变体,但我想它们都有一些缺陷(不是主要的,它们很好地解释了这个概念。)所以这里是一个,仅出于争论的目的:

def 1_by_n(n, C = 10):   #n could be float. C could be any positive number
  if n <= 0.0:           #If input is actually 0, infinite loop.
    while True:
      sleep(1)           #or pass
    return               #This line is not needed and is unreachable
  delta = 0.0001
  itr = delta
  while delta < C/n:
    itr += delta


因此,随着n的增加,该函数将花费越来越少的时间,并确保如果输入实际为0,则该函数将永远需要返回。 />有人可能会说它会受到机器精度的限制,因此它的上限是O(1),但是我们也可以通过以字符串形式输入n和C来绕过它。比较是在字符串上完成的,想法是,这样我们可以任意减小n,因此即使忽略n = 0,该函数的上限也不受限制。

我也相信不能只说运行时间是O(1 / n),而是应该说O(1 + 1 / n)

#21 楼

好的,我做了一些思考,也许有一种算法可以遵循以下一般形式:

您需要计算1000个节点图的旅行推销员问题,但是,还给出了您无法访问的节点列表。随着不可见节点列表的增加,该问题变得更容易解决。

评论


那么O(n)中的n是另一种类型。有了这个技巧,您可以说每个算法都有O(q),其中q是例如居住在中国的人口数量。

– vava
09年5月25日下午6:35

Boyer-Moore具有相似的类型(O(n / m)),但这并不是“比O(1)好”,因为n> = m。我认为您的“看不见的TSP”也是如此。

–尼基
09年5月25日下午6:39

即使在这种情况下,TSP的运行时也是NP-Complete,您只需从图中删除节点,从而有效地减小n。

–埃德·詹姆斯(Ed James)
09年5月25日在12:41

#22 楼

我看到一个公认的上限是O(1 / n)的算法:

您有大量输入,这些输入由于例程外部的某些因素而发生了变化(可能反映了硬件还是它甚至可能是处理器中执行此操作的其他内核。),您必须选择一个随机但有效的内核。并获得O(1)时间。但是,数据的动态性质使您无法创建列表,只需简单地随机探测并测试探测的有效性即可。 (请注意,本质上不能保证答案返回时仍然有效。这仍然可以使用-例如,游戏中某个单元的AI。它可能会在目标瞄准时掉落的目标上射击拉动触发器。)

这具有最坏情况下的无穷大性能,但平均情况下的性能随着数据空间的填充而降低。

#23 楼

在数值分析中,逼近算法的逼近容限应具有次恒定的渐近复杂度。

class Function
{
    public double[] ApproximateSolution(double tolerance)
    {
        // if this isn't sub-constant on the parameter, it's rather useless
    }
}


评论


您真的是说次常数还是次线性?为什么逼近算法应该是次常数的?那甚至意味着什么?

– LarsH
2010-09-29 5:45

@LarsH,近似算法的误差与步长成正比(或与步长的正幂成正比),因此步长越小,误差就越小。但是检查近似问题的另一种常用方法是与间隔被分割多少次相比的误差。间隔的分区数与步长成反比,因此误差与分区数的某些正幂成反比-随着分区数的增加,误差减小。

–雷安德鲁(Andrew Lei)
17年9月2日在2:22

@AndrewLei:哇,差不多7年后的答案!我现在比那时更了解Sam的回答。感谢您的回应。

– LarsH
17年9月2日,下午2:32

#24 楼

可以构造一个O(1 / n)的算法。一个示例是一个循环,迭代f(n)-n的倍数,其中f(n)是某个函数,其值保证大于n,并且当n接近无穷大时f(n)-n的极限为零。对于所有n,f(n)的计算也需要保持恒定。我不认为f(n)看起来会是什么样,或者这种算法有什么应用,但我认为可以存在这样的功能,但是最终的算法除了证明用O(1 / n)。

评论


您的循环需要至少花费固定时间的检查,因此生成的算法至少具有复杂度O(1)。

– Stefan Reich
19年6月10日在13:01

#25 楼

我不了解算法,但是在随机算法中出现的复杂度小于O(1)。实际上,o(1)(小o)小于O(1)。这种复杂性通常出现在随机算法中。例如,正如您所说,当某个事件的概率约为1 / n时,它们用o(1)表示。或者,当他们想说某事很有可能发生时(例如1-1 / n),他们用1-o(1)表示它。

#26 楼

如果无论输入数据如何答案都是相同的,那么您有O(0)算法。

,换句话说-在提交输入数据之前知道答案
-函数可以被优化-所以O(0)

评论


真?您仍然需要返回一个值,所以它仍然不是O(1)吗?

–约阿希姆·绍尔(Joachim Sauer)
09年5月25日在8:51

不,O(0)表示所有输入花费零时间。 O(1)是恒定时间。

– Pete Kirkham
09年5月25日在8:51

#27 楼

Big-O表示一种算法的最坏情况,与典型的运行时间不同。证明O(1 / n)算法是O(1)算法很简单。根据定义,对于所有n> = C> 0
O(1 / n)-> T(n)<= 1 / n )<= 1 / C,因为对于所有n> = C
1 / n <= 1 / C
O(1 / n)-> O(1),因为Big-O表示忽略常量(即C的值无关紧要)

评论


否:Big O表示法还用于讨论平均情况和预期时间(甚至最佳情况)方案。其余部分如下。

–康拉德·鲁道夫(Konrad Rudolph)
09年5月25日在13:23

“ O”符号无疑定义了一个上限(就算法复杂性而言,这将是最糟糕的情况)。 Ω和Theta分别表示最佳和平均情况。

–罗兰·埃瓦尔德(Roland Ewald)
09年5月25日在13:59

罗兰:那是一个误解。上限与最坏情况不同,两者是独立的概念。考虑哈希表包含算法的预期(和平均)运行时间,该运行时间可以表示为O(1)-最坏的情况可以非常精确地表示为Theta(n)!欧米茄(Omega)和塞塔(Theta)可能只是用来表示其他界限,但要再说一遍:它们与一般情况或最佳情况无关。

–康拉德·鲁道夫(Konrad Rudolph)
2009年5月25日14:17

康拉德:是的。不过,通常使用Omega,Theata和O来表示界限,如果考虑所有可能的输入,则O代表上限,等等。

–罗兰·埃瓦尔德(Roland Ewald)
09年5月25日在15:03

O(1 / n)是O(1)的子集这一事实是微不足道的,并且直接从定义中得出。实际上,如果函数g为O(h),则任何函数O(g)也是O(h)。

– Tobias
09年6月11日在17:43

#28 楼

没有什么比O(1)小
Big-O表示法表示算法的最大复杂度

如果算法的运行时间为n ^ 3 + n ^ 2 + n + 5那么它就是O(n ^ 3)
这里的低阶幂根本不重要,因为当n-> Inf时,n ^ 2与n ^ 3

无关n-> Inf,O(1 / n)与O(1)无关,因此3 + O(1 / n)与O(1)相同,从而使O(1)的计算复杂度最小br />

#29 楼

inline void O0Algorithm() {}


评论


那将是一个O(1)算法。

–拉瑟·V·卡尔森(Lasse V. Karlsen)
2010-1-23在23:54

也是如此,但要点是它不是Ω(1)。为什么我的答案被低估了?如果您认为我错了,该如何解释?

– Stewart
2010-2-16在13:55

我问过其他地方,基本上,这个答案是否正确,似乎有争议:stackoverflow.com/questions/3209139/…

– jyoungdev
2010年7月11日在14:48

好吧,它是内联的,因此您可以将其视为O(0)。但是,所有O(0)算法都是微不足道的(什么也不做),因此...不是一个非常有趣的答案。

– Stefan Reich
19年6月10日在13:13

@StefanReich是的,这不是一个很有趣的答案,但这是一个答案。

– Stewart
19年6月13日在14:13

#30 楼

这是一个简单的O(1 / n)算法。而且它甚至还可以做一些有趣的事情!

O(1 / n)是可能的,因为它描述了函数的输出如何随着输入大小的增加而变化。如果我们使用函数1 / n来描述函数执行的指令数,则对于任何输入大小,都不需要该函数接受零个指令。而是,对于每个输入大小(大于某个阈值的n),所需的指令数在上面由正常数乘以1 / n来界定。由于没有1 / n为0的实际数且常数为正,因此没有理由限制该函数采用0或更少的指令。

评论


由于O(1 / n)将落在水平线= 1以下,并且当n达到无穷大时,您的代码仍将执行给定数量的步骤,因此该算法是O(1)算法。 Big-O表示法是该算法所有不同部分的函数,它采用最大的表示法。由于该方法将始终运行某些指令,因此当n达到无限大时,您每次都会执行相同的指令,因此该方法将在恒定时间内运行。当然,不会花费很多时间,但这与Big-O表示法无关。

–拉瑟·V·卡尔森(Lasse V. Karlsen)
2010-1-23在23:55