是否有一种算法方法可以在对数时间( O(logn) )中找到未排序数组的最小值?还是只能在线性时间内实现?我不想并行。
谢谢
迈克尔
是否有一种算法方法可以在对数时间( O(logn) )中找到未排序数组的最小值?还是只能在线性时间内实现?我不想并行。
谢谢
迈克尔
如果列表未排序,则您的搜索必须至少是线性的。您必须至少查看每个项目一次,因为您未查看的任何内容都可能少于您已经看到的内容。
一般来说,并行不会有帮助。如果您的处理器多于n,并且您不计算加载数据所需的时间,即 O( n ),那么是的,您可以在对数时间内完成。但是假设每个处理器有 10 个数字。这需要一定的时间。现在让每个处理器有 20 个数字。在并行比较彼此的结果之前,每个处理器将花费两倍的时间来处理其数字。O( n )+O(logn ) =O( n )。
这不可能是线性时间,因为在 lg n步骤中您只能检查 lg n 个元素,并且因为它们是未排序的,所以这些值不包含有关数组中其他值的信息。
你的意思是最小值?
那是线性的 - 你遍历你的数组,保存最不为人知的元素的位置(或值本身)并将每个元素与之进行比较。是不是元素较低保存它。最后你有最小元素的位置(或值)。
我在 C++0x 中做了一个简短的例子:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> array({5, 3, 2, 7, 5, 1, 9});
int min = array[0];
std::for_each(array.cbegin(), array.cend(), [&min] (const int cur) {
min = std::min(cur, min);
});
std::cout << min;
}
你可以在Ideone执行它
不是线性的,但是如果使用某种修改过的快速排序,它可以比线性快于少于 10 个元素。我怀疑您正在寻找数组中少于 10 个项目:)
实现它的另一种方法是深入了解 SSE 指令的世界。
一种可以提供帮助的 OPCODE 是 CMPLEPS,它一次并行比较 4 个标量。
如果您不愿意在并行代码中执行此操作,但是我严重怀疑您是否愿意使用 SSE 汇编指令。
您还可以为此使用分而治之的递归算法,代码:
private static Integer array[];
private static Integer findMinimum(int startIndex, int endIndex){
//base case
if(startIndex + 1 == endIndex || startIndex == endIndex){
return array[startIndex] < array[endIndex] ? array[startIndex] : array[endIndex];
}
//recursive case
int a = findMinimum(startIndex, (startIndex + endIndex) / 2 );
int b = findMinimum( (startIndex + endIndex) / 2 + 1, endIndex);
return Math.min(a, b);
}
该算法的运行时间为:O(n)
但是,如果您有 N 个处理器(我知道这不是“有效的”现实世界场景,这仅对理论讨论感兴趣)。您可以进行并行计算并且运行时间为:O(log n)
所以,如果你想做一些并行计算,你可能想尝试这种方法。