随机化三分之一的快速排序是否明显优于随机快速排序?

时间:2011-02-15 09:06:31

标签: algorithm math quicksort

我刚回答了一个关于在快速排序实施中选择分区的不同方法的问题,并提出了一个我真的不知道如何回答的问题。这有点像数学,这可能是错误的网站,所以如果需要移动请告诉我,我很乐意将其移植到其他地方。

众所周知,随机均匀选择其枢轴的快速实施将最终在预期的O(n lg n)时间内运行(这是on Wikipedia的一个很好的证据)。然而,由于产生随机数的成本,许多快速分析实施不会随机选择枢轴,而是依赖于“三分之一”方法,其中确定性地选择三个元素并且选择中值作为枢。众所周知,在最坏的情况下退化为O(n 2 )(例如,参见this great paper关于如何生成那些最坏情况的输入)。

现在,假设我们结合这两种方法,从序列中挑选三个随机元素,并使用它们的中位数作为枢轴的选择。我知道这也保证了O(n lg n)平均情况运行时使用的证据与常规随机快速排序的证明略有不同。但是,我不知道在这个特定的快速排序实现中,n ng n项前面的常数因子是什么。对于常规随机快速排序维基百科列出了随机快速排序的实际运行时间,最多需要1.39 n lg n比较(使用lg作为二进制对数)。

我的问题是:有没有人知道如何使用“三分之一”随机快速排序得出比较次数的常数因子?如果我们更普遍地说,使用随机的k中值方法是否存在关于快速排序的常数因子的表达式?我很好奇,因为我觉得看看这种方法是否有一些“甜蜜点”比其他随机快速分析实施更少的比较会很有吸引力。我的意思是,能够说随机化的快速排序与随机中位数为六的枢轴选择使得比较最少,这不是很酷吗?或者能够最终说你应该随机选择一个枢轴元素?

5 个答案:

答案 0 :(得分:6)

这是常量的启发式推导。我认为它可以做得很严谨,需要付出很多努力。

令P为连续随机变量,其值为[0,1]。直观地,P是小于枢轴的值的分数。我们希望找到常数c,以便

c n lg n = E [n + c P n lg(P n)+ c(1 - P)n lg((1-P)n)]。

稍后有点代数,我们有

c = 1 / E [ - P lg P - (1 - P)lg(1 - P))]。

换句话说,c是伯努利分布的平均P的预期熵的倒数。直观地,对于每个元素,我们需要以产生大约lg n位信息的方式将其与枢轴进行比较。

当P均匀时,P的pdf为1.常数

In[1]:= -1/NIntegrate[x Log[2, x] + (1 - x) Log[2, 1 - x], {x, 0, 1}]

Out[1]= 1.38629

当枢轴的中位数为3时,P的pdf为6 x(1 - x)。常数是

In[2]:= -1/NIntegrate[6 x (1 - x) (x Log[2, x] + (1 - x) Log[2, 1 - x]), {x, 0, 1}]

Out[2]= 1.18825

答案 1 :(得分:5)

通常的随机快速排序的常量很容易计算,因为比较两个元素k个位置的概率正好是2 /(k + 1):这两个元素中的一个被选为枢轴之前的概率他们之间的任何k-1元素。不幸的是,你的算法没有那么聪明。

我犹豫是否尝试你的粗体问题,因为我可以回答你的“潜在”问题:渐渐地说,没有“甜蜜点”。计算k个元素的中值,甚至O(n 1 - ε)元素的总增加成本是线性的,并且n log n项的常数随着阵列被更均匀地分割而减小。捕获当然是线性项上的常量,这是非常不切实际的,突出了渐近分析的一个缺点。


根据我在下面的评论,我猜k = 0(n α)0 <&lt; α<&lt; 1是“甜蜜点”。

答案 2 :(得分:4)

如果集合的初始状态是随机排序的,那么你将获得完全相同的常数因子,用于随机挑选三个项目来计算中位数,就像确定性地选择三个项目一样。

随机选择项目的动机是确定性方法会给出比平均值更差的结果。如果确定性方法给出了良好的中位数,则无法通过随机选择项目来改进它。

因此,哪种方法给出最佳结果取决于输入数据,无法确定每个可能的集合。

降低常数因子的唯一可靠方法是增加用于计算中位数的项目数,但在某些时候计算中位数会比获得更好的中位数所获得的更高。< / p>

答案 3 :(得分:3)

是的,确实如此。 C standard library's qsort function的作者Bentley和McIlroy在他们的论文中写道,Engineering a Sort Function以下数字:

  • 1.386 n lg使用第一,中间或随机枢轴的平均比较
  • 1.188 n lg n平均比较使用中位数3 pivot
  • 1.094 n lg n平均比较使用中位数为3 medians pivot

根据上述文件:

  

我们的最终代码因此选择较小数组的中间元素,   中等大小的第一,中,最后元素的中位数   数组和九个均匀间隔的大的伪中位数   阵列。

答案 4 :(得分:1)

只是一个想法:如果您使用三分之一方法,并且您发现它更好,为什么不使用五分之一中位数十一方法?当你在它上面时,也许可以想到中位数优化......嗯......好吧,这显然是一个坏主意(因为你必须对序列进行排序)为此......)。

基本上,要选择您的枢轴元素作为中位数元素,您可以对那些 m 元素进行排序,对吗?因此,我只是猜测,你正在寻找的常数之一是“2”:通过首先排序3个元素来选择你的支点,你执行了多少额外的比较?让我们说它2.你在快速反应中一遍又一遍地做到这一点。一个基本结论是中位数为3 因此比简单随机快速排序慢2倍。

但是这里有什么用?你得到了一个更好的设备和征服分配,你可以更好地防止退化的情况(一点点)。

所以,回到我开头的臭名昭着的问题:为什么不从中位数-m 中选择枢轴元素,m是5,7,n / 3,左右。必须有一个最佳位置,其中 m 元素的排序比从更好的分而治之行为和快速排序获得的收益更差。我想,这个甜蜜点很早就出现了 - 如果选择 3的中位数,你必须首先对抗 2 比较的常数因子。我承认,值得做一个实验,但我不会过分期待结果:-)但如果我错了,收益很大:不要停在3点!