我正在努力更好地理解缩减,我现在正在研究两种算法,“中位数中位数”和Quicksort。
据我所知,两种算法都使用类似的(实际上相同的)分区子程序来帮助解决问题,最终使它们非常相似。
Select(A[1...n],k): // Pseudocode for median of medians
m = [n/5]
for i from 1 to m:
B[i] = Select(A[5i-4..5i],3)
mom = Select(B[1..m],m/2)
r = partition(A[1..n],mom) // THIS IS THE SUBROUTINE
if k < r:
return Select(A[1..r-1],k)
else if k > r:
return Select(A[r+1..n],k-r)
else
return mom
对于这两种算法,术语“减少”是否有意义?以下任何一项都有意义吗?
中位数/ Quicksort的中位数可以缩减为分区子程序
中位数的中位数减少为快速排序
Quicksort降低到中位数的中位数
答案 0 :(得分:3)
这实际上取决于你对“减少”的定义。
通常讨论的标准减少类型是mapping reduction(也称为多次减少)。从问题X到问题Y的映射减少如下:
给出问题X的输入I X ,将其转换为输入I Y 到问题Y.然后,在I 上运行问题Y的求解器Y 并输出答案。
在映射缩减中,您只需调用一个解决问题Y的子例程,并且必须输出从该子例程返回的任何答案。例如,您可以减少“这个数字是否均匀?”的问题。问题是“这个数字奇怪吗?”通过在数字中加1并输出结果数是否为奇数。
作为映射缩减的一个非示例,请考虑以下两个问题:首先,问题“这个列表中的每个布尔值都是真的吗?”,第二,问题“这个列表中的布尔值是假的吗?”如果你有第二个问题的求解器,你可以用它来解决第一个问题,解决第二个问题并输出相反的结果:布尔值列表中有一些元素是假的,当且仅当它不是时列表的每个元素都为true的情况。但是,这种减少不是映射减少,因为我们正在翻转子例程产生的结果。
经常使用的不同类型的缩减是Turing reduction。从问题X到问题Y的图灵减少如下:
构建一个解决问题X的算法,假设有一个魔术黑盒总能解决问题Y.
所有地图缩减都是图灵减少,但不是相反。上述减少“是一切都是真的吗?” “是虚假的东西”不是映射减少,但它是图灵减少,因为你可以使用子程序“是假的吗?”要了解列表是否包含任何错误值,那么可以输出相反的值。
映射缩减和图灵缩减之间的另一个主要区别是,在图灵缩减中,您可以多次调用解决问题Y的子程序,而不仅仅是一个。
您可以将快速排序和中位数中位数视为使用分区作为子例程的算法。在快速排序中,该子程序完成了对所有内容进行排序所需的所有繁重工作,并且在中位数中位数时,它执行缩小输入的基本步骤之一。由于两种算法都会对子例程进行多次调用,因此您可以将它们视为图灵式减少。 Quicksort是从排序到分区的减少,而中位数的中位数是从选择到分区的减少。
希望这有帮助!
答案 1 :(得分:0)
我不认为任何一种都可以减少到另一种(无论如何,以任何有意义的方式)。您可以使用中位数的中位数为Quicksort选择枢轴(但实际上几乎没有人)。 Quicksort仍然必须基于pivot元素执行一些其他步骤(具体来说,根据数据透视分区数据)。
同样地,中位数的中位数不能减少到Quicksort,因为Quicksort做了额外的工作(除其他外)阻止它满足中位数中位数的复杂性保证。