Проблема:Как выбрать наименее N элементов с ограниченным пространством?
Функция f
возвращает элементы один за один раз в неизвестном порядке. Я хочу выбрать наименьшие N
элементов. Функция f
называется много раз (я просматриваю очень сложное пространство поиска), и у меня недостаточно памяти для хранения каждого выходного элемента для будущей сортировки.
Очевидное решение:
Держите вектор N
элементов в памяти и на каждом f()
поиска минимального и максимального и, возможно, заменить что-то. Вероятно, это работает для очень маленького N
. Тем не менее, я ищу более общее решение.
Мое решение до сих пор:
Я хотя об использовании priority_queue
для того, чтобы хранить, скажем, 2N
значения и уменьшая верхнюю половину после каждого 2N
шагов.
псевдокод:
while (search goes on)
for (i=0..2N)
el = f()
pust el to the priority queue
remove N greatest elements from the priority queue
select N least elements from the priority queue
Я думаю, что это должно работать, однако, я не считаю его элегантным вообще. Возможно, уже существует какая-то структура данных, которая справляется с этой проблемой. Было бы очень просто изменить priority_queue
, чтобы выбросить элементы, которые не вписываются в сохраненный диапазон.
Не могли бы вы порекомендовать мне существующую структуру данных std
для C++ или предложить мне реализовать решение, которое я предложил выше? Или, может быть, есть отличный и элегантный трюк, о котором я не могу думать.
Вы хотите сохранить 'n минимум' элементы, и каждый раз, когда вы получаете 1 элемент, вызывая функцию' f() '. Я прав? Поэтому каждый раз вставляйте этот один элемент в priority_queue (как вы упомянули). Если размер этого 'pq' меньше, чем N, ничего не происходит, но если оно больше N (N + 1), вам нужно« поп »наибольший элемент. Что не так с этим подходом? – AKJ88
Вставка и удаление элементов в priority_queue осуществляется не бесплатно. Моя идея состояла бы в том, чтобы использовать столько места, сколько у меня, и периодически называть nth_element, чтобы получить N самых маленьких. –
@ AKJ88, поэтому вы предлагаете создать 'priority_queue' (который в основном представляет собой оболочку для структуры данных кучи), которая имеет наибольший элемент в корне и вызывать' pop' после каждого 'push'? Правильно ли я вас понимаю? Это должно фактически уничтожить наименьшие элементы N. – petrbel