任何计算机科学专业的人都知道,堆排序在理论上的最坏情况是
对于我的玩具项目 caliper-analyze,我最近一直在研究从基准测试结果中估算算法实际平均复杂度的方法。特别地,我尝试了劳森和汉森的 NNLS 拟合与不同的多项式。
然而,它还没有表现得太好。有时我会得到可用的结果,有时则不会。我想可能会有所帮助,只需进行更大的基准测试,特别是尝试更多的参数。
以下结果是用于排序Double对象的,采用SAW模式和10%的随机性。本次运行中n只有500,因此并不代表实际使用情况...这些数字是估计的运行时间与大小的依赖关系。输出结果经过手动编辑和排序,并且不反映工具当前提供的内容!
您可以看出,在这种特定情况下(通常情况下,它并不完全令人满意),结果基本上与已知行为相符:冒泡排序非常昂贵,而对于快速排序的良好启发式方法要好得多。然而,例如,具有中位数启发式方法的快速排序最终以
如果有时间,我将尝试以更多的大小重新运行其中一些基准测试,以便获得更多数据点。也许那时它就能够正常工作了...但我相信有更稳健的回归方法可以用于从较小的数据集中获得更好的估计。此外,我想检测样本是否过小以至于无法进行任何预测!
O(n log n)
,而快速排序的最坏情况是 O(n^2)
。然而,在实践中,一个良好实现的快速排序(具有良好的启发式)将在每个数据集上优于堆排序。一方面,我们几乎不会观察到最坏情况,另一方面例如 CPU 缓存行、预取等在许多简单任务中产生巨大差异。而且,例如快速排序可以处理已排序的数据(具有良好的启发式)在 O(n)
的时间复杂度内,而堆排序将始终以 O(n log n)
的时间重新组织数据,因为它没有利用现有的结构。对于我的玩具项目 caliper-analyze,我最近一直在研究从基准测试结果中估算算法实际平均复杂度的方法。特别地,我尝试了劳森和汉森的 NNLS 拟合与不同的多项式。
然而,它还没有表现得太好。有时我会得到可用的结果,有时则不会。我想可能会有所帮助,只需进行更大的基准测试,特别是尝试更多的参数。
以下结果是用于排序Double对象的,采用SAW模式和10%的随机性。本次运行中n只有500,因此并不代表实际使用情况...这些数字是估计的运行时间与大小的依赖关系。输出结果经过手动编辑和排序,并且不反映工具当前提供的内容!
BubbleSortTextbook LINEAR: 67.59 NLOG2N: 1.89 QUADRATIC: 2.51
BubbleSort LINEAR: 54.84 QUADRATIC: 1.68
BidirectionalBubbleSort LINEAR: 52.20 QUADRATIC: 1.36
InsertionSort LINEAR: 17.13 NLOG2N: 2.97 QUADRATIC: 0.86
QuickSortTextbook NLOG2N: 18.15
QuickSortBo3 LINEAR: 59.74 QUADRATIC: 0.12
Java LINEAR: 6.81 NLOG2N: 12.33
DualPivotQuickSortBo5 NLOG2N: 11.28
QuickSortBo5 LINEAR: 3.35 NLOG2N: 9.67
您可以看出,在这种特定情况下(通常情况下,它并不完全令人满意),结果基本上与已知行为相符:冒泡排序非常昂贵,而对于快速排序的良好启发式方法要好得多。然而,例如,具有中位数启发式方法的快速排序最终以
O(n + n^2)
的估计值结束,而其他快速排序则被估计为O(n + n log n)
现在是我的实际问题:
- 您是否了解从基准数据中执行运行时复杂度分析以预测哪个实现(如上所示,我有兴趣比较同一算法的不同实现!)在真实数据上表现最佳的算法/方法/工具?
- 您是否了解关于此的科学文章(估计实现的平均复杂度)?
- 您是否了解可帮助获得更准确估计的稳健拟合方法?例如,NNLS的正则化版本。
- 您是否了解需要多少样本才能获得合理估计的经验法则?(特别是,当工具应该避免给出任何估计,因为它可能会不准确?)
如果有时间,我将尝试以更多的大小重新运行其中一些基准测试,以便获得更多数据点。也许那时它就能够正常工作了...但我相信有更稳健的回归方法可以用于从较小的数据集中获得更好的估计。此外,我想检测样本是否过小以至于无法进行任何预测!