Выберите два числа на сумму

9

Вот проблема ближайшего соседа.

Учитывая реалы a1,,an (очень большой n!), плюс цель реальная p, найти ai а также aj чья сумма ближе всего p, Мы разрешаем разумную предварительную обработку / индексациюa1,,an (вплоть до O(nlogn)), но во время запроса p), результат должен быть возвращен очень быстро (например, O(logn) время).

(Более простой пример: если бы мы только хотели ОДИН ai это ближе всего к pмы бы отсортировали a1,,an не в сети, O(nlogn)затем выполните бинарный поиск во время запроса, O(logn)).

Решения, которые не работают:

1) Сортировка a1,,anв автономном режиме, затем во время запроса начните с обоих концов и переместите два указателя внутрь ( http://bit.ly/1eKHHDy ). Не хорошо, из-заO(n) время запроса.

2) Сортировка a1,,an в автономном режиме, а затем во время запроса, принять каждый ai и выполнить бинарный поиск для «приятеля», который помогает ему суммировать что-то близкое к p, Не хорошо, из-заO(nlogn) время запроса.

3) Сортировка всех пар (a1,,an)в автономном режиме, а затем сделать бинарный поиск. Не хорошо, из-заO(n2) Предварительная обработка.

Спасибо!

пс. Дальнейшие обобщения, необходимые для практики: (1)a1,,an а также p быть 50-мерными векторами, (2) "близко", чтобы быть векторным косинусным расстоянием, и (3) k-бест ближайших пар-та-сумма, а не только 1-лучший.

Kevin
источник
Есть ли ограничение на время предварительной обработки или объем пространства, которое мы можем использовать после предварительной обработки? Если мы ограниченыO(n) пространство, есть ли у вас основания полагать, что это можно решить, скажем, O(lgn)время? Это кажется мне невероятно маловероятным.
DW
Предварительная обработка ограничена O (n журнал n). Я обновил постановку задачи.
Кевин
У меня нет оснований полагать, что запросы могут быть быстрыми, но многие полезные результаты для ближайших соседей (kd-деревья, локальное хеширование и т. Д.) Кажутся мне нелогичными. Примерное решение с использованием локально-чувствительного хеширования подойдет для практического использования.
Кевин

Ответы:

17

Это почти наверняка невозможно.

Предположим, вы можете решить свою проблему с предварительной обработкой времени P(n) и время запроса Q(n), Тогда есть простой алгоритм для решения проблемы 3SUM - предоставлен наборn действительные числа, суммируют ли какие-либо три элемента ноль? P(n)+nQ(n)время. Мы предварительно обрабатываем все числа, затем для каждого числаakмы находим значение ai+aj это ближе всего к ak; если это соответствуетak точно, мы нашли решение проблемы 3SUM.

Тем не менее, самый быстрый алгоритм, известный для 3SUM работает в O(n2)время, и этот алгоритм широко предположил, чтобы быть оптимальным. Кроме того, есть соответствиеΩ(n2)нижняя граница в ограниченной, но естественной модели дерева решений. Для наборов целых чисел существуют слегка субквадратичные алгоритмы времени, которые «играют в игры с битами», но даже в модели целочисленного ОЗУ 3SUM предположительно требуетΩ(n2/polylogn) время.

Таким образом, предполагая, что гипотеза верна, ваша задача требует либо (почти) квадратичного времени предварительной обработки, либо (почти) времени линейного запроса.

Jeffε
источник
2

Если вы можете использовать неограниченное пространство и неограниченное время во время предварительной обработки, то следующее решение отвечает вашим требованиям:

  • Во время предварительной обработки вычислить набор {ai+aj:1ijn}и сохраните этот набор в отсортированном порядке. Этот набор может быть создан и отсортирован вO(n2) время, и это занимает O(n2) место для его хранения.

  • Теперь, чтобы ответить на запрос (найти ai,aj где ai+aj как можно ближе к pнасколько это возможно), просто выполните бинарный поиск в этом отсортированном списке. Что займетO(lgn) время.

Если это решение неприемлемо, вам нужно более тщательно продумать свои требования и соответствующим образом отредактировать вопрос.

DW
источник
Привет и спасибо! Но ваше решение совпадает с моим решением № 3, которое проблематично из-за времени предварительной обработки O (n ^ 2). В моем случае n очень большое (например, 1 м), и я должен избегать O (n ^ 2) операций.
Кевин