Алгоритм поиска ближайшей точки


18

У меня есть список нескольких сотен городов с их широтой / долготой. Учитывая другое местоположение (также в лат / лонг) мне нужно найти ближайший город.

Поскольку я не использую ГИС, к настоящему времени очевидным алгоритмом является создание цикла для всех городов, вычисляющего расстояние между точками.

Создание цикла практически выполнимо для меня, но есть какой-то простой в реализации алгоритм, позволяющий сделать это более эффективно? Или какая-нибудь легкая библиотека Java, которая может помочь решить это?

Примечания : Мне не нужно / не нужно полное ГИС-решение или тяжелая / сложная библиотека. Я предпочитаю менее хорошее, но простое и легкое решение, потому что это единственное, что мне нужно решить.


Значит, не важно, что расстояние не будет правильным? И вы не хотите учитывать дороги, которые могут сделать один город дальше другого (диагональ против квадрата)?
— Брэд Несом

Да дороги для меня не важны. Мне нужен ближайший город на линейном расстоянии, потому что это для прогнозов погоды.
— Lujop

1
Прогнозы погоды? Я надеюсь, что у вас есть суперкомпьютер и штат обученных метеорологов.
— Майкл Тодд

Прогнозы сделаны Майкл, только я должен взять ближайший :)
— Lujop

Ответы:


24

Именно этот вопрос я исследовал 20 лет назад при разработке настольной ГИС. Нам нужно было находить расстояния между точками в интерактивном режиме; наша цель состояла в том, чтобы сделать вычисления менее чем за 1/2 секунды для тысяч точек. Тестирование (на 486 ПК с частотой 25 МГц!) Показало, что мы можем вычислить все расстояния в точности так, как вы описываете (с помощью простого очевидного алгоритма), так быстро, что нет смысла создавать более сложное решение, такое как структура дерева квадрантов. ,

Для вычисления расстояний до одной точки «зондирования» ваши варианты включают (а) проекцию всех точек с использованием эквидистантной проекции с центром в точке зонда или (b) принятие модели сферической земли и использование формулы Хаверсайна . Первое уместно, если вам нужна точность эллипсоидальной модели. В любом случае вычисления выполняются достаточно быстро и, вероятно, занимают менее 1000 тиков: вы можете запросить около миллиона точек в секунду с помощью одного процессора.

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

Если вам нужно идти быстрее, вы можете использовать различные приближения для отображения точек. Например, если вы находитесь между -88 и +88 градусами широты, а ближайшая найденная точка находится на расстоянии 200 км, то любая точка, широта которой отличается от широты зонда более чем на 2 градуса, не может быть ближе (потому что где-нибудь на земля, один градус широты превышает около 110 км). Во многих случаях этот вид предварительной проверки может позволить вам обрабатывать сотни миллионов точек в секунду.


1
Для обсуждения формулы haversine см. Gis.stackexchange.com/q/4906/664
— whuber

4

Я согласен с другими, что простой цикл должен быть эффективным для «нескольких сотен городов».

Учитывая вашу заявку, работа с эллипсоидальными расстояниями, вероятно, является чрезмерным излишним - вы, вероятно, имеете дело с прогнозами погоды, местонахождение которых едва достигает нескольких метров. Сферическая геометрия достаточно проста, чтобы вы могли легко сделать это в своем цикле.

Это может быть еще проще (например, используйте delta lat в качестве y и delta lon * cos (lat) в качестве x и найдите минимум x ^ 2 + y ^ 2). Вы используете косинус целевой широты, который вы рассчитываете только один раз. Это будет все более и более неточным для отдаленных городов, но они все равно будут отклонены, так что не имеет значения. Предполагая, что ваш ближайший город, как правило, находится в пределах пары сотен километров, шансы на другой результат (ближайший город) с использованием этого и более точной формулы весьма малы и будут происходить только в том случае, если различия достаточно малы, чтобы «какой прогноз был Точность "вероятно будет зависеть от других факторов в любом случае (то есть: потеря в шуме).

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


1

Это в дополнение к тому, что уже было сказано, но я подумал, что хотел бы отметить важность выбора соответствующей структуры данных. Я написал свой собственный код для K-функции в .NET и обнаружил, что использование эффективных коллекций значительно ускорило процесс. Извините, я не знаю обозначения O для точных скоростей. Я использовал два словаря для координат x и y с идентификатором точки в качестве ключа. Я не знаю Java, поэтому ничего не могу предложить.

Ура, Дэвид

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.