Нахождение самой близкой точки к данной точке

В Python вы можете сказать ...

isPrimaryColor = someColor in ('Red', 'Blue', 'Yellow')

... который я нахожу более читабельным, чем ваш синтаксис (== "Red" or == "Blue"). Есть несколько причин для добавления поддержки синтаксиса для языковой функции:

  • Эффективность : здесь нет причин, так как нет улучшения скорости.
  • Функциональность : тоже не проблема; в новом синтаксисе вы ничего не можете сделать, чего не можете сделать в старом.
  • Разборчивость : большинство языков прекрасно справляются со случаем, когда вы проверяете равенство нескольких значений. В других случаях (например, someNumber (> 1 and < 10)) это может быть более полезным, но даже тогда это не приносит вам большой выгоды (а Python позволяет вам сказать 1 < someNumber < 10, что еще яснее).

Так что не ясно, предложенные изменения особенно полезны.

11
задан luvieere 7 October 2009 в 22:09
поделиться

5 ответов

Поскольку вы находитесь на iPhone, вы можете использовать CoreLoaction для определения географического расстояния - используя CLLocation - getDistanceFrom:

У меня возникло бы искушение использовать линейный поиск грубой силы, хотя все 2k точек и, если этого недостаточно, переключитесь на что-то вроде GeoHash для хранения метаданных по вашим точкам для поиска.

2
ответ дан 3 December 2019 в 10:04
поделиться

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

Быстрый поиск предоставляет следующий пример javascript:

var R = 6371; // km Radius of earth
var dLat = (lat2-lat1).toRad();
var dLon = (lon2-lon1).toRad(); 
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * 
        Math.sin(dLon/2) * Math.sin(dLon/2); 
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
var d = R * c;

С точки зрения структуры данных, стоит обратить внимание на Geohash .

5
ответ дан 3 December 2019 в 10:04
поделиться

Если вам нужно лучше, чем O (N), вы можете получить это, только если сначала заплатите N lg N за построение какого-либо пространственного хеша (квадродерево, октодерево, хеш-сетку или аналогичный). Тогда каждый тест будет примерно O (lg N) и может быть намного лучше, если кешировать последнее проверенное вами место, если есть большая когерентность (как правило, есть).

Я бы, вероятно, построил октодерево в Эйлере (геоцентрическое, XYZ) пространство, потому что это позволяет мне получить "истинное" расстояние, а не "искаженное" расстояние широты / долготы. Однако на практике четырехугольное дерево в пространстве широты и долготы, вероятно, будет работать достаточно хорошо. Получив совпадение, вы держитесь за этот узел дерева (при условии, что дерево не перестраивается во время выполнения), и следующий запрос начинается с этого узла дерева,

5
ответ дан 3 December 2019 в 10:04
поделиться

Почему бы не разбить земной шар на регионы? (Подумайте о гексагонах.) Затем, либо когда вы добавляете точки в свой список, либо в одном большом цикле предварительной обработки для каждой точки, сохраните регион, в котором она находится.

Затем, при поиске точек рядом с точкой A в шестнадцатеричном формате X , вам нужно проверить только точки в гексагоне X и максимум 3 соседних гекса.

Если это все еще слишком много точек для проверки, добавьте подобласти.

1
ответ дан 3 December 2019 в 10:04
поделиться

Я думаю, что этот алгоритм работает:

Создать массив, отсортированный по широте Создайте массив, отсортированный по долготе

Чтобы найти ближайший, сначала найдите ближайший по широте на выполняет двоичный поиск в массиве широт. Сделайте то же самое для массива долготы. Теперь у вас 2 очка, один ближайший по широте, второй по долготе. Вычислите расстояния до каждой точки с помощью теоремы Пифагора. Побеждает ближайшая точка.

Роджер

-3
ответ дан 3 December 2019 в 10:04
поделиться