开发者

Finding the minimum in an unsorted array in logarithmic time

开发者 https://www.devze.com 2023-02-19 18:11 出处:网络
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.

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.

开发者_StackOverflow

Thanks

Michael


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.


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).


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.


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


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消