在对数时间内找到未排序数组中的最小值

发布于 2024-10-26 02:33:29 字数 89 浏览 7 评论 0原文

是否有一种算法方法可以在对数时间( O(logn) )内找到未排序数组的最小值?或者只能在线性时间内实现?我不想并行。

谢谢

迈克尔

Is there an algorithmic approach to find the minimum of an unsorted array in logarithmic time ( O(logn) )? Or is it only possible in linear time? I don't want to go parallel.

Thanks

Michael

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

-残月青衣踏尘吟 2024-11-02 02:33:29

如果列表未排序,则您的搜索必须至少是线性的。您必须至少查看每个项目一次,因为您没有查看过的任何内容可能都会少于您已经看过的内容。

If the list is unsorted, your search has to be at least linear. You must look at each item at least once, because anything you haven't looked at might be less than what you've already seen.

通知家属抬走 2024-11-02 02:33:29

一般来说,并行并没有什么帮助。如果您的处理器数量多于n,并且您不计算加载数据所需的时间,即 O(n) ,那么是的,你可以在对数时间内完成。但假设每个处理器有 10 个数字。这需要一定的时间。现在每个处理器有 20 个数字。在并行比较彼此的结果之前,每个处理器将花费两倍的时间来处理其数字。 O(n) + O(log n) = O(n)。

Going parallel wouldn't help in general. If you have more processors than n, and you don't count the time it takes to load the data, which is O(n), then yes, you can do it in logarithmic time. But suppose you have, say, 10 numbers per processor. It takes a certain amount of time. Now make it 20 numbers per processor. Each processor will take twice as long to crunch its numbers, before they compare each other's results in parallel. O(n) + O(log n) = O(n).

对不⑦ 2024-11-02 02:33:29

它不可能在线性时间内,因为在 lg n 步骤中,您只能检查 lg n 元素,并且因为它们是未排序的,所以这些值不包含有关其他值的信息数组。

It is not possibly in linear time, because in lg n steps you can only inspect lg n elements, and because they are unsorted, the values carry no information about other values in the array.

你与昨日 2024-11-02 02:33:29

你是说最小值?

这是线性的 - 您迭代数组,保存最不为人知的元素的位置(或值本身)并将每个元素与其进行比较。元素是否较低,请保存它。最后你得到了最小元素的位置(或值)。

我用 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 执行它

You mean the minimal value?

That is linear - you iterate through your array, save the position (or value itself) of the least known element and compare every element to that. Is the element lower save that instead. At the end you have the position (or value) of the least element.

I made an short example in 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;
}

You can execute it at Ideone

你与昨日 2024-11-02 02:33:29

线性排序不是,但是如果使用某种改进的快速排序,对于少于 10 个元素,它可以比线性排序更快。我怀疑您正在寻找数组中少于 10 个的项目:)

实现它的另一种方法是深入研究 SSE 指令的世界。

CMPLEPS 是一种可以提供帮助的操作码,它一次并行比较 4 个标量。

如果您不愿意在并行代码中执行此操作,但我严重怀疑您是否愿意使用 SSE 汇编指令。

Linearly not, however it can be faster than linear for less than 10 elements if using some sort of modified quicksort. I doubt you are looking to less than 10 items in the array :)

The other way to achieve it is to dwell into the world of SSE instructions.

One OPCODE that could help is CMPLEPS which compares in parallel 4 scalars at a time.

If you are not willing to do that in parallel code however I seriously doubt you would like to use SSE assembly instructions.

迷鸟归林 2024-11-02 02:33:29

您还可以为此采用分而治之的递归算法,代码:

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)

因此,如果您想做一些并行计算,您可能需要尝试这种方法。

You can also have a divide and conquer recursive algorithm for this, code:

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);
}

This algorithm has a running time of: O(n)

However, if you have N processor(I know this is not a "valid" real world scenario, this is interesting only for theory discussions). You can have parallel calculations and have a running time of: O(log n)

So, if you want to do some parallel computations you might want to try this approach.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文