Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Python kdtree найти n ближайших соседних групп (координат)

Автор вопроса: TriОтветов: 2

Цель: по заданной координате X найти "n" ближайших прямых-многоугольников для координаты X, а не просто "n" ближайших точек. Пример: https://i.imgur.com/qyxV2MF.png


У меня есть группа пространственных линейных многоугольников, которые могут иметь более двух координат. Их координаты хранятся в (scipy)KDtree, чтобы обеспечить поиск NN.

Во-первых, я запрошу "i" количество ближайших координат, а затем найду соответствующие линии-многоугольники-> "i" координаты не обязательно могут давать "i" строки.

Чтобы получить "n" ближайших строк, мне нужно будет увеличить "i". Моя проблема в том, что "i" может быть непредсказуемым, потому что количество координат варьируется между каждым линейным многоугольником. Например, линия-многоугольник может быть представлена ​​2 координатами, а другая может быть представлена ​​10 координатами. В большинстве случаев мне нужны только 2 ближайших соседних линейных многоугольника из точки X.

В примере изображения мне нужны линии A и B в качестве результата. Даже при "i" = 3 будет найдена только линия A, потому что A1, A2, A3 являются ближайшими соседями X.


Вопрос: есть ли способ сгруппировать координаты фигуры вместе, а затем выполнить поиск NN, чтобы получить "n" уникальных фигур? (кроме грубого форсирования "i", чтобы обеспечить "n" уникальных форм)


Текущий псевдокод обходного пути:

found = []
while True:
    if first_loop:
        result = look up N nearest coords
    else:
        result = look up Nth nearest coord

    look up shapes using result and append to found
    perform de-duplication of found

    if len(found) >= required:
         return found
    else:
         N = N+1 # to check the Nth neighbor next iteration
  • Имеет ли смысл преобразовывать ваши группы в средние/средние баллы? Итак, вы должны перевести свою проблему в точку NN, сопоставить k ближайших точек, а затем разложить эти совпадения на исходные группы. randomir 27.08.2018
  • Привет, randomir, я тоже подумал о представлении каждой формы с использованием одиночных координат. Однако мои геопространственные формы также различаются по размеру, поэтому использование центроидов для ближайших соседей может не дать желаемого результата (мне нужно не более 4 для каждого запроса). Представьте себе дорожную сеть в форме звезды, где я нахожусь в центре, а от нее расходятся 5 дорог (форм). Технически расстояние между 5 дорогами и мной одинаковое. Но если мы используем центроиды в качестве ориентира, длина дороги будет иметь значение. Tri 27.08.2018

pythonalgorithmdata-structuresnearest-neighborkdtree

Ответы

Ответ 1 · Sandipan Dey

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

Пусть у нас есть следующие структуры данных: 1. Словарь из линейных полигонов в точки 2. Другой словарь из точек в линейные полигоны (или, что то же самое, одна двунаправленная карта из bidict вместо пары словарей) 3. Логический массив посетили с размером, равным количеству баллов

Теперь следующий алгоритм должен решить вашу проблему (может быть эффективно реализован с помощью вышеуказанных структур данных):

  1. Для всех точек инициализируйте посещаемый массив как False.

  2. Сначала найдите ближайшую точку к точке запроса из kd-дерева, отметьте совпадающую точку и все точки из соответствующего многоугольника, к которому совпавшая точка принадлежит, как посещенные, и верните этот конкретный многоугольник (id) как ближайший многоугольник (если есть таких полигонов несколько, вернуть все).

  3. Повторяйте шаг 2, пока не будет возвращено n таких (различных) полигонов. Считайте новую точку, возвращенную из kd-дерева, совпавшей с точкой запроса, если она еще не посещена (если совпавшая точка, возвращенная kd-деревом, уже посещена, отбросьте ее и запросите следующую ближайшую совпавшую точку). Как только точка будет посещена, пометьте точку и все точки из соответствующего многоугольника (ов) как посещенные и верните многоугольник (и).

Ответ 2 · SaiBot

Я вижу два способа сделать это эффективно:

  1. Индексируйте полные "линейные многоугольники": для этого вы можете ограничить каждый линейный многоугольник минимальным ограничивающим прямоугольником. Затем проиндексируйте все прямоугольники с помощью соответствующей структуры индекса, такой как R-Tree. Вместо точек у вас будут линии-многоугольники на самом нижнем уровне, поэтому вам придется адаптировать расстояние для этого случая.
  2. Используйте просмотр на расстоянии: идея Здесь нужно прикрепить к каждой точке идентификатор ее линейного многоугольника и проиндексировать точки в индексной структуре (например, KD-Tree). Затем вы последовательно извлекаете следующую ближайшую точку к вашему запросу, используя дистанционный просмотр. Вы продолжаете это, пока не найдете точки n различных линий-многоугольников.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы