Как найти медиану большого количества целых чисел (они не помещаются в памяти)

Я знаю, что в ответе используется медиана медиан, но может ли кто-нибудь объяснить, как это сделать?


person user2316569    schedule 04.05.2013    source источник
comment
Здесь есть несколько тем на SO: Тема 1, Тема 2. И есть другие   -  person keyser    schedule 04.05.2013
comment
Найдите медиану каждой выборки значений, которые умещаются в памяти, и возьмите медиану из них.   -  person Peter Lawrey    schedule 04.05.2013
comment
Я нашел код для быстрого выбора, если он вам все еще нужен   -  person aaronman    schedule 03.07.2013


Ответы (3)


Для этого существуют алгоритмы линейного времени, эта страница может быть полезной, http://en.wikipedia.org/wiki/Selection_algorithm, если вы все еще не уверены, просто спросите

По сути, алгоритм выбора работает как быстрая сортировка, но каждый раз он сортирует только на стороне поворота. Цель состоит в том, чтобы продолжить разбиение до тех пор, пока вы не выберете точку поворота, равную индексу элемента, который вы пытались найти. Вот код Java, который я нашел для быстрого выбора:

public static int selectKth(int[] arr, int k) {
 if (arr == null || arr.length <= k)
  throw new Error();

 int from = 0, to = arr.length - 1;

 // if from == to we reached the kth element
 while (from < to) {
  int r = from, w = to;
  int mid = arr[(r + w) / 2];

  // stop if the reader and writer meets
  while (r < w) {

   if (arr[r] >= mid) { // put the large values at the end
    int tmp = arr[w];
    arr[w] = arr[r];
    arr[r] = tmp;
    w--;
   } else { // the value is smaller than the pivot, skip
    r++;
   }
  }

  // if we stepped up (r++) we need to step one down
  if (arr[r] > mid)
   r--;

  // the r pointer is on the end of the first k elements
  if (k <= r) {
   to = r;
  } else {
   from = r + 1;
  }
 }

 return arr[k];
}
person aaronman    schedule 04.05.2013
comment
Спасибо, но у меня вопрос, как использовать алгоритм, когда все числа не умещаются в памяти. Может кто-нибудь, пожалуйста, подробно объясните - person user2316569; 05.05.2013
comment
для этого алгоритма не обязательно сразу все числа находиться в памяти, прочтите его - person aaronman; 05.05.2013
comment
спасибо - не могли бы вы подтвердить мое понимание? Сначала я занесу в память первые пять чисел и найду их медиану с помощью алгоритма выбора. Сохраняю результат в памяти. Затем я заношу в память следующие пять чисел - и сохраняю их медиану в памяти. И так далее. т.е. в итоге у меня в памяти останется n / 5 номеров. Теперь я запускаю алгоритм выбора среди них, чтобы найти медиану этих чисел. - person user2316569; 05.05.2013
comment
Да, и затем вы используете алгоритм выбора, потому что у вас есть гарантированно хороший поворот - person aaronman; 05.05.2013
comment
Другое возможное решение - поддержание медианы по мере роста списка, если это вариант. - person aaronman; 05.05.2013

вот алгоритм медианы медианы.

person stinepike    schedule 04.05.2013
comment
Спасибо, но у меня вопрос, как использовать алгоритм, когда все числа не умещаются в памяти. Может кто-нибудь, пожалуйста, подробно объясните - person user2316569; 04.05.2013
comment
Хорошо, я отправляю описание, когда у меня будет время - person stinepike; 05.05.2013

См. Первые два ответа на этот вопрос. Если первый (подсчет частоты) может работать для ваших данных / доступного хранилища, вы можете получить точный ответ таким образом. Второй (лечебный) - надежный общий метод.

person Phil Steitz    schedule 04.05.2013
comment
Существует также алгоритм с двумя кучами, который использует минимальную и максимальную кучу параллельно, чтобы найти медиану с постоянной памятью даже с большими числами. - person Thomas Jungblut; 04.05.2013
comment
Не могли бы вы дать ссылку, Томас, на этот алгоритм двух куч с постоянной памятью? - person Phil Steitz; 05.05.2013
comment
см. stackoverflow.com/questions/2579912/ - person Thomas Jungblut; 05.05.2013
comment
Спасибо, Томас. Возможно, я неправильно понимаю настройку в статье, но я не вижу привязанного к ней хранилища. Похоже, что в итоге оказывается куча, включающая все значения. Что мне не хватает? - person Phil Steitz; 05.05.2013