Расположение всех элементов между начальной и конечной точками, заданными значением (не индексом) - PullRequest
3 голосов
/ 11 мая 2011

Проблема в следующем:

Мне бы дали набор координат x и y (массив координат от 30 до 40 тысяч) длинной веревки.Веревка лежит на земле и может иметь любую форму.

Теперь мне бы дали начальную точку (по существу, координаты x и y) и конечную точку.

Каков эффективный способ определения набора координат x и y из вышеупомянутого массива координат, лежащего между начальной и конечной точками.

Исчерпывающий поиск, т. Е. Зацикливание 40k раз, не приемлемрешение (упомянутое в вопросном документе)

Допускается незначительный запас для ошибки

Ответы [ 4 ]

4 голосов
/ 12 мая 2011

Нам нужно найти начальную точку в массиве, затем конечную точку. Для каждого мы можем думать о веревке как о функции расстояния от этой точки, и мы ищем самую низкую точку на этом графике расстояний. Если одна точка находится далеко, а другая довольно близко, мы можем сделать какое-то интерполяционное предположение о том, где искать дальше.

distance
    |  /---\
    |--     \  /\       -
    |        --  ------- --   ------     ----------    -
    |                      \ /      \---/          \--/
    +-----------------------X--------------------------- array index

В приведенном выше представлении мы хотим найти «X» ... мы смотрим на расстояния в нескольких точках, получая представление о наклоне кривой расстояний, возможно, даже о скорости изменения этого наклона, чтобы Помогите нам в следующем исследовании ...

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

  • если нам дана длина веревки и мы знаем, что выборки координат равноудалены вдоль веревки, то мы можем рассчитать максимальное изменение расстояния от нашей целевой точки на выборку.
  • если мы знаем, что канат имеет жесткость, гарантирующую, что он не может зацикливаться на тривиально малом диаметре, то
    • есть известный предел того, насколько быстро может измениться наклон кривой
    • Кривая расстояния сходится к вертикали по обе стороны от точки 0
  • Вы можете потенциально перекрестно ссылаться / комбинировать расстояние с или использовать вместо этого направление каждой точки от цели: только у цели направление мгновенно изменится на ~ 180 градусов (от того, насколько хорошо точки данных фиксируют это, все еще зависит от расстояние между соседними образцами и любая жесткость каната).

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

0 голосов
/ 08 января 2013

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

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

Это означает, что все, что вы действительно ищете, это индексы двух предоставленных координат. Или индекс один, а ответ «вторая координата направо или налево?».

Простое решение O (n) для этого будет:

For each index in array
    coord = array[index]
    if (coord == point1)
        startIndex = index
    if (coord == point2) 
        endIndex = index

if (endIndex < startIndex)
    swap(startIndex, endIndex)

return array.sublist(startIndex, endIndex)

Или, если вы хотите оптимизировать повторяющиеся запросы, я бы предложил подход, основанный на хешировании, в котором вы отображаете каждую координату в индекс в массиве. Что-то вроде:

//build the map (do this once, at init)
map = {}
For each index in array
    coord = array[index]
    map[coord] = index

//find a sublist (do this for each set of start/end points)
startIndex = map[point1]
endIndex = map[point2]

if (endIndex < startIndex)
    swap(startIndex, endIndex)

return array.sublist(startIndex, endIndex)

Это O (n) для построения карты, но как только она будет построена, вы можете определить подсписок между любыми двумя точками в O (1). Предполагая, конечно, эффективную хэш-карту.

Обратите внимание, что если мое предположение не выполняется, то те же решения по-прежнему могут использоваться, при условии, что в качестве первого шага вы берете предоставленные начальную и конечную точки и определяете точки в массиве, которые лучше всего соответствуют каждой из них. Как уже отмечалось, если вам не даны некоторые ограничения в отношении толщины веревки, то интерполяция от произвольной координаты до той, которая фактически является частью веревки, может быть в лучшем случае только догадкой.

0 голосов
/ 15 мая 2011

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

Однако, если мы предположим, что длинные участки веревки находятся на прямой линии, то мы можемисключите множество точек на основе проверки наклона:

if (abs(slope(x[i],y[i],x[i+1],y[i+1])
        -slope(x[i+1],y[i+1],x[i+2],y[i+2]))<tolerance)
    eliminate (x[i+1],y[i+1]);

Это значительно сократит время поиска, если большие участки веревки находятся на прямой линии.Но WRT будет линейным числом оставшихся точек.

0 голосов
/ 11 мая 2011

Для одноразового поиска иногда линейный обход является самым простым и быстрым решением.Может быть, дело в этой проблеме.

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

Редактировать: Это не предполагает никаких дополнительных ограничений, кроме упомянутых @koool.Ограничение расстояния между точками позволило бы подняться на гору, описанный в ответе @ Tony.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...