Мне нужно рассчитать бегущую медиану:
Ввод: , , вектор .k ( x 1 , x 2 , … , x n )
Вывод: vector , где - это медиана .y i ( x i , x i + 1 , … , x i + k - 1 )
(Нет мошенничества с приближениями; я хотел бы иметь точные решения. Элементы являются большими целыми числами.)
Существует тривиальный алгоритм, который поддерживает дерево поиска размера ; общее время работы . (Здесь «дерево поиска» относится к некоторой эффективной структуре данных, которая поддерживает вставки, удаления и срединные запросы в логарифмическом времени.)O ( n log k )
Тем не менее, это кажется немного глупым для меня. Мы эффективно изучим всю статистику заказов во всех окнах размера , а не только в медианах. Более того, на практике это не слишком привлекательно, особенно если велико (большие деревья поиска имеют тенденцию быть медленными, накладные расходы на потребление памяти нетривиальны, эффективность кеширования часто низкая и т. Д.).к
Можем ли мы сделать что-нибудь существенно лучше?
Существуют ли нижние оценки (например, является ли тривиальный алгоритм асимптотически оптимальным для модели сравнения)?
Изменить: Дэвид Эппштейн дал хороший нижний предел для модели сравнения! Интересно, возможно ли все же сделать что-то немного более умное, чем тривиальный алгоритм?
Например, можем ли мы сделать что-то в этом духе: разделить входной вектор на части размера ; сортировать каждую часть (отслеживая исходные позиции каждого элемента); а затем использовать кусочно отсортированный вектор, чтобы эффективно найти текущие медианы без каких-либо вспомогательных структур данных? Конечно, это все равно будет , но на практике сортировка массивов, как правило, происходит намного быстрее, чем поддержка деревьев поиска.O ( n log k )
Изменить 2: Saeed хотел увидеть некоторые причины, почему я думаю, сортировка быстрее, чем операции дерева поиска. Вот очень быстрые тесты для , : n = 10 8
- ≈ 8 с: сортировка векторов с элементами каждыйк
- ≈ 10 с: сортировка вектора с элементами
- ≈ 80 с: вставок и удалений в хеш-таблице размерак
- ≈ 390 с: вставок и удалений в сбалансированном дереве поиска размерак
Хеш-таблица существует только для сравнения; это не имеет прямого использования в этом приложении.
Таким образом, мы имеем почти 50-кратное различие в производительности сортировки и сбалансированных операциях дерева поиска. И все станет намного хуже, если мы увеличим .
(Технические детали: Данные = случайные 32-разрядные целые числа. Компьютер = типичный современный ноутбук. Тестовый код был написан на C ++ с использованием стандартных библиотечных процедур (std :: sort) и структур данных (std :: multiset, std :: unsorted_multiset). Я использовал два разных компилятора C ++ (GCC и Clang) и две разные реализации стандартной библиотеки (libstdc ++ и libc ++). Традиционно std :: multiset был реализован как высокооптимизированное красно-черное дерево.)