Fisher-Yates随机算法的复杂度


15

这个问题是关于费舍尔-耶茨算法的,该算法用于返回给定数组的随机混洗。在维基百科页面称,其复杂度为O(n),但我认为这是O(n log n)的。

在每个迭代i中,在1和i之间选择一个随机整数。简单地将整数写到内存中就是O(log i),由于有n次迭代,所以总数为

O(log 1)+ O(log 2)+ ... + O(log n)= O(n log n)

天真的算法效果不佳。我在这里想念什么吗?

注意:天真的算法是在(0,1)区间为每个元素分配一个随机数,然后根据分配的数字对数组进行排序。

Answers:


24

我怀疑像大多数算法一样,这里读写位数字的成本被假定为常数。只要您不被带走并使P和PSPACE意外崩溃,这就是轻微的罪过。O(logn)


4
虽然这确实是“次要的罪过”,但我认为这是TCS教育学的主要罪过,因此从未明确提及!每一位CS学生都会自己发现这一点,并认为某个重大问题是错误的,直到被告知每个人都知道这一点,但没人会谈论它。而且,几年前有人利用O(log n)模型为某个著名问题(推测为Omega(n ^ 3))提供次立方时间算法时,会不会引起麻烦?有没有解决?
randomwalker

2
我不了解您所指的烦恼。至于不提,你绝对是对的。在我首先阅读了Jeff Erickson的文章之后,现在我很想证明我的几何课中P = PSPACE仅用于踢球:)
Suresh Venkat 2010年

1
感谢您的回答。我从来不知道这有什么大不了的。该链接提供了很好的阅读。
Tomer Vromen 2010年

1
底线:始终使模型明确。
Jukka Suomela 2010年

2
我认为让位操作为恒定时间的主要原因是(对于多项式时间)您可以为所有O log n 位操作数对编程一个恒定时间访问查找表。“现代”计算模型。对于我来说,这没有什么“罪恶的”……我认为这一特性可以简单地假定为具有通用性。O(logn)O(logn)
瑞安·威廉姆斯

17

计算的标准模型假定对O(log n)位整数的算术运算可以在恒定时间内执行,因为这些运算通常在硬件中进行。因此,在Fisher-Yates算法中,“将整数i写入内存”仅需要O(1)时间。

当然,从位操作角度分析算法是非常有意义的,但是位成本模型对实际行为的预测较少。即使是简单的循环也for i = 1 to n: print(i)需要O(n log n)位操作。


循环好点。从来没有注意到...
Tomer Vromen 2010年

8

这是对“ [Fisher-Yates算法]并不比朴素算法好。我在这里遗漏了什么吗?”的答案。您在问题中问过的。

在使用实数的“幼稚”算法中:您使用多少位精度?如果您要计算位复杂度(就像您对Fisher-Yates所做的那样),并且该算法使用k个随机位作为实数,则其运行时间为Ω(kn log n),因为将两个k-位实数需要Ω(k)时间。但是k必须至少为Ω(log n)才能防止两个元素映射到相同的实数,这意味着该算法需要Ω(n log 2 n)的时间,比Fisher-Yates混洗慢了a记录因子n。

如果仅计算算术和比较运算的数量而忽略它们的位复杂度,则Fisher-Yates为Θ(n),而算法为Θ(n log n),仍然相距log n。


我怀疑是“幼稚”的算法有这样的隐ķ...
托默Vromen

1
“天真”算法可以在线性时间内按如下方式清晰地实现。为每个元素分配一个介于1和n ^ 3之间的随机整数,然后通过基数排序以O(n)时间对数字进行排序。(极有可能,没有两个元素会获得相同的随机数。如果有重复,则递归地对其进行改组。)
Jeffε10年

@JeffE:谢谢!这非常干净,并且具有与Fisher-Yates相同的复杂性。发布此内容后,我实际上感觉到“天真”算法应该不会更糟……我错过了n个k位数字可以用O(nk)排序而不需要O(nklog n)的事实。但是我猜想Knuth-Fisher-Yates的常数仍然更好:它需要精确(log n!)随机位-从1到n,然后从1到n-1的随机整数,等等。 3n log n),并且可以仅使用恒定的额外内存就地完成。
ShreevatsaR

6

对于此问题,整数没有什么特别的。

例如,如果哈希函数必须读取整个值以计算其哈希值,则哈希表(存储任何类型的值)的访问时间不会为O(1)。n个唯一元素平均需要log n个位来表示,无论您的表示多么聪明,任何读取其整个输入的哈希函数都至少需要花费相同的时间来计算。在实践中,它们比红黑树要快,但渐近而言它们并没有更好。

randomwalker引用的问题是关于POPL 2008论文(http://portal.acm.org/citation.cfm?doid=1328438.1328460),在此处进行了讨论:http : //blog.computationalcomplexity.org/2009/05/shaving- logs-with-unit-cost.html

在那篇文章中,兰斯·福特诺(Lance Fortnow)描述了一个学生,他如何抱怨排序实际上需要n log ^ 2 n次,如果我们必须读取两个元素的所有log n位以进行比较,这似乎是一个合理的反对。


我没有博客文章的作者。他抱怨说排序实际上是O(n log ^ 2 n),但是然后说纸是固体的?
Tomer Vromen 2010年

本文是可靠的(即不是虚假的),因为存在一个模型,其中算术运算需要单位时间,并且在该模型中,本文的算法是第一个实现o(n ^ 3)个运算的算法。
戴夫·多蒂

我没有收到O(n log ^ 2 n)异议,因为就位而言,输入本身的大小为O(n log n)。顺便说一句,顺便说一句,复杂性博客上的评论质量比那时高得多。……
arnab 2010年

4

维基百科页面说它的复杂度是O(n),但我认为它是O(n log n)。

实际上,在排序为O(n log n)的模型中,O(n log n)是此问题的下限。如果所有排列的可能性均等,则该算法作为从随机流到排列的函数必须是排斥的。有n!因此,在决策树模型之类的东西中,存在至少长度为O(log n!)= O(n log n)的分支。

1ϵO(ϵ


3

在TCS中,我们考虑-除非另有明确说明-图灵机上的复杂性。尽管从理论上讲这很好,但是由于我们确实在硬件中实现了不同的机器模型(即有限近似),因此结果在实践中并不是很有帮助。因此,问这些模型的复杂性是一个可行的问题。例如,我们通常假设寄存器机器(类似于真实的CPU)可以在恒定的时间内对两个寄存器执行原子操作-这就是此处可能采用的方法。

简而言之:您以TM来思考,文章作者以RM来思考。你们都是对的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.