fuz*_*fuz 25 sorting algorithm comparison performance
我在我想要进行排序阵列的应用一个元件的一个0,一个1,...,A N-1 .我有一个比较功能CMP(I,J) ,其比较元件一个我和一个Ĵ和交换功能的交换(I,J) ,该交换元件一个我和一个Ĵ阵列的.在应用程序中,cmp(i,j)函数的执行可能非常昂贵,以至于cmp(i,j)的一次执行比排序中的任何其他步骤花费的时间更长(除了其他cmp(i,j) )当然要求).你可能会认为cmp(i,j)是一个相当冗长的IO操作.
请假设为了这个问题,没有办法让cmp(i,j)更快.假设所有可能使cmp(i,j)更快的优化已经完成.
是否有一种排序算法可以最小化对cmp(i,j)的调用次数?
在我的应用程序中可以编写一个昂贵的谓词(i,j),如果调用cmp(i,j)需要很长时间,则该谓词是真的.昂贵的(i,j)便宜且昂贵(i,j)∧昂贵(j,k)→昂贵的(i,k)大部分都在我目前的应用中.但这并不能保证.
昂贵(i,j)的存在是否允许更好的算法试图避免昂贵的比较操作?如果是的话,你能指点我这样的算法吗?
我想指出有关这个主题的更多材料.
这是一个与我的应用程序完全不同的示例.
考虑一组可能很大的文件.在此应用程序中,目标是在其中查找重复文件.这基本上归结为通过一些任意的标准对文件进行排序,然后按顺序遍历它们,输出遇到的相同文件的序列.
当然,大量数据中的读取器是昂贵的,因此,例如,可以仅读取每个文件的第一兆字节并计算该数据的散列函数.如果文件比较相等,则散列也是如此,但反过来可能不成立.两个大文件只能在接近结尾的一个字节中有所不同.
在这种情况下,昂贵的(i,j)的实现只是检查哈希值是否相等.如果是,则需要进行昂贵的深度比较.
我会尽力回答每个问题.
传统的排序方法可能有一些变化,但一般来说,对列表排序所需的最小比较数量存在数学限制,并且大多数算法都利用了这一点,因为比较通常并不便宜.您可以尝试按其他方式进行排序,或尝试使用可能更接近真实解决方案的快捷方式.
我不认为你可以解决至少进行最小数量比较的必要性,但你可以改变你比较的东西.如果您可以比较数据的哈希值或子集而不是整个事物,那肯定会有所帮助.您可以采取的任何简化比较操作的方法都会产生很大的不同,但如果不了解数据的具体细节,就很难提出具体的解决方案.
看看这些:
平均排序n个元素数组所需的理论最小比较次数是lg(n!),约为n lg n -n.如果您使用比较来对元素进行排序,那么平均没有办法比这更好.
在标准的O(n log n)基于比较的排序算法中,mergesort进行最低比较次数(仅约n lg n,而快速排序约为1.44 n lg n,而对于heapsort约为n lg n + 2n),因此它可能是一个很好的算法用作起点.通常,mergesort比heapsort和quicksort慢,但这通常假设比较快.
如果你确实使用mergesort,我建议使用像自然mergesort这样的mergesort的自适应变体,这样如果数据大部分被排序,那么比较的数量就更接近线性.
还有其他一些选择.如果您知道数据已经大部分已排序,您可以使用插入排序或标准版本的heapsort来尝试加快排序.或者,您可以使用mergesort,但在n很小时使用最佳排序网络作为基本情况.这可能会减少足够的比较,从而为您带来显着的性能提升.
希望这可以帮助!
快速排序和合并排序是最快的排序算法,除非您有有关要排序的元素的一些附加信息。他们需要 O(n log(n)) 次比较,其中 n 是数组的大小。数学证明任何通用排序算法都不可能比它更有效。
如果您想让过程更快,您可以考虑添加一些元数据来加速计算(除非您也是如此,否则不能更精确)。
如果您知道更强的东西,例如最大值和最小值的存在,则可以使用更快的排序算法,例如基数排序或桶排序。
您可以在维基百科上查找所有提到的算法。
据我所知,你无法从昂贵的关系中受益。即使你知道这一点,你仍然需要进行这样的比较。正如我所说,您最好尝试缓存一些结果。
这是算法的描述。毫无疑问,它的性能会比简单的合并排序差很多,除非 m 大而 k 小。总运行时间为 O[n^4 + E(nm)log(k)],其中 E 是昂贵比较的成本(我假设 E >> n,以防止它从渐近符号中消失。 n^4 可能可以进一步减少,至少在平均情况下是这样。