ЦЕЛОЕ ЭЛЕМЕНТЫ:
Если типом ваших элементов являются целые числа, то лучше всего иметь ведро для каждого числа, лежащего в любом из ваших поддиапазонов, где каждое ведро используется для подсчета числа, связанного с ним целого числа, найденного в ваших элементах ввода (например, , bucket[100]
хранит количество 100
во входной последовательности). В основном вы можете добиться этого, выполнив следующие шаги:
- создавать корзины для каждого номера, лежащего в любом из ваших поддиапазонов.
- перебирать все элементы для каждого числа
n
, если у нас есть bucket[n]
, то bucket[n]++
.
- вычислить медианы на основе агрегированных значений, хранящихся в ваших корзинах.
Другими словами, предположим, что у вас есть поддиапазон [0, 10]
, и вы хотите вычислить медиану. Подход ведра в основном вычисляет, сколько 0
во входных данных, сколько 1
во входных данных и так далее. Предположим, что есть n
чисел, лежащих в диапазоне [0, 10]
, тогда медиана - это n/2
-й по величине элемент, который можно определить, найдя i
такое, что bucket[0] + bucket[1] ... + bucket[i]
больше или равно n/2
, но bucket[0] + ... + bucket[i - 1]
меньше n/2
.
Приятно то, что даже ваши входные элементы хранятся на нескольких машинах (то есть в распределенном случае), каждая машина может поддерживать свои собственные корзины, и только агрегированные значения требуются для передачи через интрасеть.
Вы также можете использовать иерархические сегменты, которые включают несколько проходов. На каждом проходе bucket[i]
подсчитывает, что количество элементов во входных данных находится в определенном диапазоне (например, [i * 2^K, (i+1) * 2^K]
), а затем сужает проблемное пространство, определяя, в каком сегменте будет находиться носитель после каждого шага, а затем уменьшает K
на 1
в следующий шаг и повторяйте, пока не сможете правильно определить носитель.
ЭЛЕМЕНТЫ ПЛАВАЮЩЕЙ ТОЧКИ
Все элементы могут уместиться в памяти:
Если все ваши элементы могут уместиться в памяти, лучше всего сначала отсортировать элемент N, а затем найти медианы для каждого поддиапазона. линейный решение с кучей времени также хорошо работает в этом случае, если количество ваших поддиапазонов меньше logN
.
Все элементы не помещаются в память, а хранятся на одном компьютере:
Обычно для внешней сортировки обычно требуется три сканирования диска. Следовательно, если количество ваших поддиапазонов больше или равно 3, то сначала сортировка N элементов, а затем поиск медиан для каждого поддиапазона путем загрузки только необходимых элементов с диска - лучший выбор. В противном случае лучше просто выполнить сканирование для каждого поддиапазона и выбрать эти элементы в поддиапазоне.
Все элементы хранятся на нескольких машинах: так как определение медианы является целостным оператором, то есть вы не можете получить окончательную медиану всего ввода на основе медиан нескольких частей ввода, это сложная проблема. что невозможно описать его решение несколькими предложениями, но исследования есть (см. this в качестве примера) были сосредоточены на этой проблеме.
person
keelar
schedule
12.08.2013
0,1,2,100
не равна 50. - person Bernhard Barker   schedule 12.08.20135,2,7,3,6
с диапазоном[5,7]
) - (1) Тривиально простая проблема поиска среднего значения на основе индекса. Результат здесь будет5,2,7
- ›2
. (2) То же, что и 1., за исключением того, что мы сначала сортируем числа (@Blorgbeard, это то, что вы имели в виду?), поэтому5,2,7
- ›2,5,7
-›5
. (3) Извлеките все значения в этом диапазоне, верните среднее значение, которое в примере будет5,7,6
- ›7
. (4) То же, что и 3., за исключением того, что сначала отсортировано, что в примере будет5,7,6
- ›5,6,7
-›6
(классическое определение среднего, мой ответ). - person Bernhard Barker   schedule 12.08.20130..3
вы имеете в виду0..2
, верно? :) - person Blorgbeard   schedule 13.08.2013