Python: ускорение географического сравнения

Я написал код, который включает вложенный цикл, в котором внутренний цикл выполняется примерно 1,5 миллиона раз. У меня есть функция в этом цикле, которую я пытаюсь оптимизировать. Я проделал некоторую работу и получил некоторые результаты, но мне нужен небольшой вклад, чтобы проверить, разумно ли то, что я делаю.

Немного предыстории:

У меня есть две коллекции географических точек (широта, долгота) , одна относительно небольшая коллекция и одна относительно большая коллекция. Для каждой точки в маленькой коллекции мне нужно найти ближайшую точку в большой коллекции.

Очевидный способ сделать это - использовать формулу гаверсинуса. Преимущество здесь в том, что расстояния определенно точны.

from math import radians, sin, cos, asin, sqrt

def haversine(point1, point2):
    """Gives the distance between two points on earth.
    """
    earth_radius_miles = 3956
    lat1, lon1 = (radians(coord) for coord in point1)
    lat2, lon2 = (radians(coord) for coord in point2)
    dlat, dlon = (lat2 - lat1, lon2 - lon1)
    a = sin(dlat/2.0)**2 + cos(lat1) * cos(lat2) * sin(dlon/2.0)**2
    great_circle_distance = 2 * asin(min(1,sqrt(a)))
    d = earth_radius_miles * great_circle_distance
    return d

Однако выполнение 1,5 миллиона раз на моей машине занимает около 9 секунд (по данным timeit). Поскольку точное расстояние неважно, мне нужно только найти ближайшую точку, я решил попробовать другие функции.

Простая реализация теоремы Пифагора дает мне ускорение примерно на 30%. Думая, что у меня получится лучше, я написал следующее:

def dumb(point1, point2):
    lat1, lon1 = point1
    lat2, lon2 = point2
    d = abs((lat2 - lat1) + (lon2 - lon1))

, что дает мне улучшение в 10 раз. Однако теперь я беспокоюсь, что это не сохранит неравенство треугольника.

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

11
задан Wilduck 11 July 2011 в 20:58
поделиться