Вот проблема ближайшего соседа.
Учитывая реалы (очень большой !), плюс цель реальная , найти а также чья сумма ближе всего , Мы разрешаем разумную предварительную обработку / индексацию (вплоть до ), но во время запроса ), результат должен быть возвращен очень быстро (например, время).
(Более простой пример: если бы мы только хотели ОДИН это ближе всего к мы бы отсортировали не в сети, затем выполните бинарный поиск во время запроса, ).
Решения, которые не работают:
1) Сортировка в автономном режиме, затем во время запроса начните с обоих концов и переместите два указателя внутрь ( http://bit.ly/1eKHHDy ). Не хорошо, из-за время запроса.
2) Сортировка в автономном режиме, а затем во время запроса, принять каждый и выполнить бинарный поиск для «приятеля», который помогает ему суммировать что-то близкое к , Не хорошо, из-за время запроса.
3) Сортировка всех пар в автономном режиме, а затем сделать бинарный поиск. Не хорошо, из-за Предварительная обработка.
Спасибо!
пс. Дальнейшие обобщения, необходимые для практики: (1) а также быть 50-мерными векторами, (2) "близко", чтобы быть векторным косинусным расстоянием, и (3) -бест ближайших пар-та-сумма, а не только 1-лучший.
Ответы:
Это почти наверняка невозможно.
Предположим, вы можете решить свою проблему с предварительной обработкой времениP(n) и время запроса Q(n) , Тогда есть простой алгоритм для решения проблемы 3SUM - предоставлен наборn действительные числа, суммируют ли какие-либо три элемента ноль? P(n)+n⋅Q(n) время. Мы предварительно обрабатываем все числа, затем для каждого числаak мы находим значение ai+aj это ближе всего к −ak ; если это соответствует−ak точно, мы нашли решение проблемы 3SUM.
Тем не менее, самый быстрый алгоритм, известный для 3SUM работает вO(n2) время, и этот алгоритм широко предположил, чтобы быть оптимальным. Кроме того, есть соответствиеΩ(n2) нижняя граница в ограниченной, но естественной модели дерева решений. Для наборов целых чисел существуют слегка субквадратичные алгоритмы времени, которые «играют в игры с битами», но даже в модели целочисленного ОЗУ 3SUM предположительно требуетΩ(n2/polylogn) время.
Таким образом, предполагая, что гипотеза верна, ваша задача требует либо (почти) квадратичного времени предварительной обработки, либо (почти) времени линейного запроса.
источник
Если вы можете использовать неограниченное пространство и неограниченное время во время предварительной обработки, то следующее решение отвечает вашим требованиям:
Во время предварительной обработки вычислить набор{ai+aj:1≤i≤j≤n} и сохраните этот набор в отсортированном порядке. Этот набор может быть создан и отсортирован вO(n2) время, и это занимает O(n2) место для его хранения.
Теперь, чтобы ответить на запрос (найтиai,aj где ai+aj как можно ближе к p насколько это возможно), просто выполните бинарный поиск в этом отсортированном списке. Что займетO(lgn) время.
Если это решение неприемлемо, вам нужно более тщательно продумать свои требования и соответствующим образом отредактировать вопрос.
источник