Visibility graph и motion planning — различия между версиями
Igorjan94 (обсуждение | вклад) (→Motion planning) |
Igorjan94 (обсуждение | вклад) м (→Motion planning) |
||
Строка 114: | Строка 114: | ||
Если полигон вращать нельзя, задачу сводится к движению точки так : выбирается точка на полигоне, которая принимается за начало координат. В такой системе координат для каждого препятствия считается [[Сумма Минковского (определение, вычисление)|сумма Минковского]] с полигоном. Получаются бОльшие препятствия, но теперь достаточно двигать выбранную точку, что было описано выше. | Если полигон вращать нельзя, задачу сводится к движению точки так : выбирается точка на полигоне, которая принимается за начало координат. В такой системе координат для каждого препятствия считается [[Сумма Минковского (определение, вычисление)|сумма Минковского]] с полигоном. Получаются бОльшие препятствия, но теперь достаточно двигать выбранную точку, что было описано выше. | ||
− | Если полигон можно вращать, задача нахождения ''кратчайшего'' пути становится достаточно ресурсоёмка, поэтому обычно рассматривают | + | Если полигон можно вращать, задача нахождения ''кратчайшего'' пути становится достаточно ресурсоёмка, поэтому обычно рассматривают задачу нахождения какого-нибудь пути между конечными точками. |
− | Первый шаг решения этой задачи совпадает с предыдущим случаем : выберем точку и построим [[Сумма Минковского (определение, вычисление)| | + | Первый шаг решения этой задачи совпадает с предыдущим случаем : выберем точку и построим [[Сумма Минковского (определение, вычисление)|сумму Минковского]] препятствий с полигоном. Рассмотрим малый угол <tex> \epsilon </tex>. Представим, что поворот полигона на этот угол {{---}} это движение вверх-вниз между слоями, на каждом из которых посчитана сумма Минковского с полигоном, повернутым на этот угол. |
На каждом слое построим трапецоидную карту и граф, как описано в [[Visibility graph и motion planning#Нахождение пути между точками с препятствиями|начале]]. Если [[Пересечение многоугольников (PSLG overlaying)|пересечь]] соседние слои и добавить между их графами ребра, получится один большой граф, в котором ищется кратчайший путь. | На каждом слое построим трапецоидную карту и граф, как описано в [[Visibility graph и motion planning#Нахождение пути между точками с препятствиями|начале]]. Если [[Пересечение многоугольников (PSLG overlaying)|пересечь]] соседние слои и добавить между их графами ребра, получится один большой граф, в котором ищется кратчайший путь. | ||
− | При таком подходе может возникнуть ошибка при пересечении слоев : на каждом слое состояния будут допустимые, а осуществить поворот физически будет невозможно. Обычно, эту проблему решают двумя способами : измельчением угла поворота и изначальным сглаживанием углов полигона. Первый способ повышает не только точность решения, но вычислительную сложность задачи. Второй подход практически исключает возможность нахождения пути, когда его нет, но повышает вероятность "ненахождения" пути, когда он есть. | + | При таком подходе может возникнуть ошибка при пересечении слоев : на каждом слое состояния будут допустимые, а осуществить поворот физически будет невозможно. Обычно, эту проблему решают двумя способами : измельчением угла поворота и изначальным сглаживанием углов полигона. Первый способ повышает не только точность решения, но и вычислительную сложность задачи. Второй подход практически исключает возможность нахождения пути, когда его нет, но повышает вероятность "ненахождения" пути, когда он есть. |
== Источники == | == Источники == |
Версия 19:31, 9 февраля 2015
Содержание
Нахождение пути между точками с препятствиями
Для начала рассмотрим движение материальной точки. Случай, когда размером и формой движимого объекта пренебречь нельзя, будет рассмотрен позднее.
Обычно эта задача решается с помощью трапецоидной карты. По ней строится граф, ребра которого соединяют центры трапедоидов, а также начальную и конечную вершины с серединами вертикальных сторон трапецоидов. В таком графе ищется путь между начальной и конечной вершинами.
Данный алгоритм работает за
и за линейное количество памяти и идеально подходит для нахождения какого-нибудь пути между конечными вершинами. Но иногда нужно найти кратчайший путь, и этот алгоритм не подходит, хоть и дает хорошее приближение. Однако, решения нахождения кратчайшего пути в лучшем случае работают за времени и памяти (здесь и далее — количество всех вершин).Visibility graph
Рассмотрим точное решение нахождения кратчайшего пути на плоскости между двумя точками с полигональными препятствиями с помощью построения графа видимости. После его построения, как и в случае с трапецоидной картой, кратчайший путь ищется любым стандартным алгоритмом поиска (например, алгоритмом Дейкстры или A*).
Для простоты рассуждений начальную и конечную вершины будем считать вершинами полигонов.
Лемма (О кратчайшем пути): |
Любой кратчайший путь между двумя вершинами с полигональными препятствиями представляет собой ломаную, вершины которой — вершины полигонов. |
Доказательство: |
Пусть кратчайший путь — не ломаная. В таком случае, на пути существует такая точка , которая не принадлежит ни одному прямому отрезку. Это означает, что существует -окрестность точки , в которую не попадает ни одно препятствие (случай, когда точка попала на ребро рассматривается аналогично). В таком случае, подпуть, который находится внутри -окрестности, по неравенству треугольника может быть сокращён по хорде, соединяющий точки пересечения границы -окрестности с путем. Раз часть пути может быть уменьшена, значит и весь путь может быть уменьшен, а значит исходное предположение некорректно. |
Определение: |
Говорят, что вершина | видна (англ. mutually visible) из , если отрезок не пересекает ни одного препятствия.
Определение: |
Граф видимости (англ. visibility graph) — граф, вершины которого — вершины полигонов. Между вершинами | и существует ребро, если из видна .
В худшем случае в таком графе может быть ребер. Однако по некоторым ребрам кратчайший путь точно не пройдет, и такие ребра из графа можно удалить.
Лемма: |
Доказательство: |
Путь проходящий через ребро будет длиннее, чем через соседей точки , так как по неравенству треугольника |
По доказанным леммам любое ребро кратчайшего пути содержится в графе. Таким образом, для нахождения кратчайшего пути осталось найти кратчайший путь в этом графе от начальной до конечной вершины.
Построение visibility графа
Наивный алгоритм.
Для каждой пары вершин проверяем, можно ли добавить ребро между ними, то есть нет ли пересечений с полигонами.
пар вершин и ребер, то есть .Lee’s Algorithm.
Однако можно это сделать за . Идея алгоритма проста : для каждой вершины найдем видимые из нее вершины. Если научиться делать это за , задача решена, так как всего точек .Для каждой вершины будем рассматривать только правую половину плоскости, так как ребра, которые должны идти в левую половину, будут исходить из вершин, для которых текущая вершина будет справа. Переформулируем задачу. Дано : точка и множество отрезков — ребер препятствий. Найти : множество концов отрезков, видимых из .Для решения этой задачи будем использовать заметающий луч с началом в точке . Его статусом будут отрезки, которые его пересекают, упорядоченные по возрастанию расстояния от точки до точки пересечения. Точками событий будут концы отрезков.Пустим луч из рассматриваемой вершины вертикально вверх и добавим в статус все отрезки, которые он пересекает, по увеличению расстояния до них. Теперь будем рассматривать точки в порядке сортировки по углу между и вертикальной полуосью . При таком обходе проверка видимости вершины будет выполняться за , так как достаточно проверить пересечение с отрезком, первым в статусе. Действительно, если вершина не видна, то отрезок пересекает несколько отрезков, лежащих перед , а значит и ближайший, то есть первый в статусе. В противном случае все пересекаемые лучом отрезки лежат за вершиной и пересечения отрезка с ближайшим отрезком в статусе не будет. Вне зависимости от видимости вершины, необходимо изменить статус заметающего луча. Для этого необходимо удалить из статуса все отрезки, которые заканчиваются вершине (лежат слева от прямой ) и добавить все отрезки, которые в ней начинаются (лежат справа от прямой ).Псевдокодgraph buildVisibilityGraph(Set<Segment> segments) Set<Vertex> vertices = getVertices(segments) //получаем все вершины препятствий graph visibilityGraph(vertices) //изначально в графе только вершины for Vertex v in vertices //для каждой вершины for Vertex w in getVisibleVertices(v, segments) //добавляем в граф все видимые из нее вершины visibilityGraph.addEdge(v, w) return visibilityGraph Здесь функция getVisibleVertices( ) возвращет все видимые из вершины и выглядит так:vector<Vertex> getVisibleVertices(vertex v, set<segment> segments) // Инициализируем статус for segment s in segments if intersection s and ray from v to up exists status.add(s) // Инициализируем множество вершин, которые нужно рассматривать for point w in segments if w.x >= v.x currentVertices.add(w) sort(currentVertices) by angle // Для каждой вершины проверяем, видима ли она и обновляем статус for w in currentVertices if intersection vw and status.first not exists answer.add(w) delete from status all edges ending in w add in status all edges beginning in w return answer В качестве статуса нужно использовать структуру данных, позволяющую добавлять и удалять из нее отрезки за и извлекать минимум за или . В этом случае достигается асимптотика , так как для каждой из точек выполняется сортировка( ), обновление статуса (суммарно , так как каждый отрезок добавляется и удаляется из статуса только один раз) и запросы ближайшего отрезка ( или на точку, то есть или ). |
Overmars and Welzl’s Algorithm
visibility graph при помощи rotation tree
C помощью rotation tree можно достичь асимптотики .
Motion planning
Рассмотрим задачу нахождения кратчайшиго пути, когда движимый объект — это выпуклый полигон. Например, робот, которого надо доставить из начальной в конечную точку.
Если полигон вращать нельзя, задачу сводится к движению точки так : выбирается точка на полигоне, которая принимается за начало координат. В такой системе координат для каждого препятствия считается сумма Минковского с полигоном. Получаются бОльшие препятствия, но теперь достаточно двигать выбранную точку, что было описано выше.
Если полигон можно вращать, задача нахождения кратчайшего пути становится достаточно ресурсоёмка, поэтому обычно рассматривают задачу нахождения какого-нибудь пути между конечными точками.
Первый шаг решения этой задачи совпадает с предыдущим случаем : выберем точку и построим сумму Минковского препятствий с полигоном. Рассмотрим малый угол . Представим, что поворот полигона на этот угол — это движение вверх-вниз между слоями, на каждом из которых посчитана сумма Минковского с полигоном, повернутым на этот угол.
На каждом слое построим трапецоидную карту и граф, как описано в начале. Если пересечь соседние слои и добавить между их графами ребра, получится один большой граф, в котором ищется кратчайший путь.
При таком подходе может возникнуть ошибка при пересечении слоев : на каждом слое состояния будут допустимые, а осуществить поворот физически будет невозможно. Обычно, эту проблему решают двумя способами : измельчением угла поворота и изначальным сглаживанием углов полигона. Первый способ повышает не только точность решения, но и вычислительную сложность задачи. Второй подход практически исключает возможность нахождения пути, когда его нет, но повышает вероятность "ненахождения" пути, когда он есть.
Источники
- Mark de Berg, Otfried Cheong, Marc van Kreveld, Mark Overmars (2008), Computational Geometry: Algorithms and Applications (3rd edition), Springer-Verlag, ISBN 978-3-540-77973-5 Chapter 15 page 324-331
- статья про visibility graphs на academia.edu
- Хабр
Ссылки
- Моя реализация алгоритма за . Далеко от идеального, но работает