Изменения

Перейти к: навигация, поиск

Трапецоидная карта

2040 байт добавлено, 01:44, 18 февраля 2015
Модификация трапецоидной карты
<div style="background-color: #ABCDEF; font-size: 16px; font-weight: bold; color: #000000; text-align: center; padding: 4px; border-style: solid; border-width: 1px;">Эта статья находится в разработке!</div><includeonly>[[Категория: В разработке]]</includeonly> Трапецоидная карта {{---}} геометрическая структура позволяющая локализоваться на площади за <tex>\mathcal{O}(\log(n))</tex>данных для локализации в конфигурации отрезков.
==Постановка задачи==
Предположим, у нас есть наши координаты, и есть карта мира. Мы можем найти по карте наше местоположение и сказать в какой стране мы находимся.Области задаются замкнутыми ломаными. '''Формальная постановка задачи'''  Есть множество конфигурация отрезков на плоскостии dcel-подобная структура, позволяющая по ребру из конфигурации получить соответствующий face.Есть запрос (точка <tex>q</tex>)Трапецоидная карта позволяет найти ребро, на выходе {{--до которого можно дойти от точки-}} областьзапроса, в которой находится точка <tex>q</tex>не пересекая образующие конфигурацию отрезки.
==Структура данных==
У нас есть множество отрезков, ограниченных оболочкой <tex>R</tex>(это не выпуклая оболочка, а просто мнимая граница плоскости, за которую не вылезают отрезки).
Мы договариваемся, что никакие две точки не лежат на одной вертикали(в противном случае всё ещё противнее). ''Трапецоидная карта'' множества отрезков <tex>S</tex> {{---}} это эти отрезки и множество трапецоидов построенных следующим образом, из каждой точки выпущены два луча {{---}} вверх и вниз, до первого пересечения с другим отрезком или с оболочкой <tex>R</tex>.
{{Лемма
|statement= Любой <tex>\operatorname{face}</tex> трапецоидной карты ограничен одним или двумя вертикальными отрезками и обязательно двумя не вертикальными отрезками.
}}
[[Файл:Trapezoidmapnavigationshagal.jpgpng|650px|thumb|right|навигация в трапецоидной картеТрапецоидная карта]]
Именно отсюда берется название структуры, так как любой <tex>\operatorname{face}</tex> либо трапеция, либо треугольник.
|proof=
*''вершины'', а точнее откуда они берутся.
[[Файл:Trapezoidmapnavigationleftpshagal.jpg|400px|thumb|right|варианты leftp(<tex>\Delta</tex>)]]
**4 вершины уходит на оболочку <tex>R</tex>
**<tex>2 \cdot n</tex> концы отрезков
}}
Хранить трапецоиды можно в чем угодно. Вместе с самим трапецоидом, стоит хранить <tex>\operatorname{leftp}</tex>, <tex>\operatorname{rightp}</tex>, <tex>\operatorname{top}</tex> и <tex>\operatorname{bottom}</tex>. Так же Также следует хранить соседей трапецоида.
----
[[Файл:Trapezoidmapsearchstructureshagal.png|650px|thumb|right|навигация в трапецоидной карте]]
*''Поисковая структура''
Поисковая структура представляет из себя ациклический граф с одним корнем и соответствующими трапецоидам листьями.
У каждого узла есть два ребенка. При этом узел может быть двух типов.
[[Файл:Trapezoidmapsearchstructureshagal.jpg|650px|thumb|right|навигация в трапецоидной карте]]
*Первый тип узла - точка, соответствующая концу отрезка.
*Второй тип узла - отрезок.
Во время запроса мы двигаемся по графу от его корня до момента, когда окажемся в листе. Это и будет означать, что точка находится внутри трапецоида. Если мы находимся не в листе, то мы должны опредетиться, в каком из детей мы окажемся дальше.
Еcть два правила:
*Если текущий узел соответсвует вершине, то смотрим левее или правее мы находимся(проверка по <tex>x</tex>-координате)выбираем лексикографически нужную.*Если текущий узел соответствует отрезку, то смотрим , выше или ниже мы находимся(проверка по <tex>y</tex>-координате). *Плохие случаи: Мы находимся на одной вертикали с вершиной Мы находимся на отрезке (Решение: молиться, или просто обрабатывать вручную.)
==Алгоритм==
[[Файл:Trapezoidmapnotsuchbadcaseshagal.jpgpng|400px|thumb|right|простой случай]]Во время построения трапецоидной карты(в дальнейшем <tex>T</tex>) алгоритм так же также строит структуру для поиска. Так как трапецоидная карта {{---}} геометрическая структура, а основные операции ведутся именно с поисковой, основной упор делается на неё.
Наш алгоритм добавляет отрезки по одному и, после каждого добавления, модидицирует модифицирует <tex>T</tex> и <tex>D</tex>.
''Порядок добавления отрезков''
От порядка добавления зависит время запроса. Как? Время запрос пропорцианально запроса пропорционально глубине графа.
Считается, что , если добавлять отрезки в случайном порядке, то время будет хорошим. Почему и какое время будет достигаться, расписано дальше.
===Алгоритм===
*Создали новые трапецоиды.
[[Файл:TrpezoidmapbadcaseshagalTrpezoidmapbadcaseshaga.jpgpng|400px|thumb|right|сложный случай]]
===Поиск трапецоидов, которые пересек отрезок===
Чтобы модифицировать карту, мы должны понять, где произошло изменение.
Оно произошло в тех трапецоидах, которые пересек текущий отрезок, или можно сказать, что трапецоид с <tex>i-1</tex>-ой итерации не будет в <tex>i</tex>-ой только если его пересек отрезок.
Пусть якобы есть множество трапецоидов <tex>\Delta_0, \Delta_1, \Delta_2 \ldots \Delta_k</tex>, упорядоченное по <tex>s_i</tex>
Пусть <tex>\Delta_{j+1}</tex> {{---}} один из правых соседей <tex>\Delta_j</tex>. Так жеТакже, при этом не сложно несложно понять, каким соседом он является.
Если <tex>\operatorname{rightp} \Delta_j</tex> лежит выше <tex>s_i</tex>, то сосед нижний и наоборот.
Это значит, что, если мы знаем первый трапецоид, то мы можем найти остальные , просто обходя по карте соседей справа.
Чтобы найти первый трапецоид, нужно просто локализовать правый конец в текущей карте.
Есть два случая.
*'''Простой ''' {{---}} отрезок не пересекает ни одного трапецоида, то есть целиком внутри.
Тогда удаляем этот старый трапецоид и на его место ставим дерево из двух концов отрезка, отрезка и четырех образовавшихся трапецоидов.
Важно не забыть правильно определить соседей новых трапецоидов.
В случае, если какие-то трапецоиды выродятся в треугольники, будет не четыре новых трапецоида, а 2 или 3. Слава богу это не самая большая проблема*Находим множество трапецоидов, которых пересек отрезок (в данном случаи он один).*Находим этот трапецоид в <tex> T </tex> и добавляем вместо него нужные трапецоиды.*Спускаемся по <tex> D </tex> до соответствующего трапецоида.*Вместо этого трапецоида добавляем ключ "x" и строим оттуда часть структуры, как показано на картинке.
*Сложный {{---}} отрезок пересекает сразу несколько трапецоидов.
*'''Сложный''' {{---}} отрезок пересекает сразу несколько трапецоидов. Итак , наш отрезок пересекает трапецоиды <tex>\Delta_0, \Delta_1, \Delta_2 ... \Delta_k</tex>.
Сначала добавляем вертикальные лучи из концов текущего отрезка. Это нужно, чтобы модифицировать <tex>\Delta_0</tex> и <tex>\Delta_k</tex>.
<tex>\Delta_0, \Delta_1, \Delta_2 \ldots \Delta_k</tex>.
*Находим множество трапецоидов, которых пересек отрезок.
*Находим этот трапецоид в <tex> T </tex> и добавили вместо него нужные трапецоиды.
*Спускаемся по <tex> D </tex> до соответствующих трапецоидов.
*Вместо них добавляем новые ключи, как показано на картинке.
 
Заметим, что не нужно каждый раз хранить все трапецоиды, которые пересек отрезок. Можно менять структуру во время поиска этих трапецоидов.
Если идти по отрезку слева направо, то, как только отрезок пересек очередное вертикальное дополнение, новый трапецоид левее этого дополнения заканчивается и больше изменяться не будет. Мы можем сразу поменять структуру.
Таким образом, сложный случай сводится к простому.
===Модификация трапецоидной карты===
Совместим update и алгоритм поиска новых трапецоидов.
Находим первый трапецоид, в который попал новый отрезок.
Предположим, у нас простой случай, то есть менять нужно только один трапецоид.
В таком случае мы сразу его модифицируем.
 
Если новый отрезок пересекает несколько трапецоидов.
Рассмотрим момент, когда текущий трапецоид заканчивается и мы начинаем рассматривать его соседей.
Очевидно, что если мы модифицируем закончившийся трапецоид, мы по прежнему сможем рассматривать его соседей.
При этом модификацию мы проводим так же, как в простом случае.
 
'''Update'''(Segment s)
Point p <tex>\leftarrow</tex> s.start
Point q <tex>\leftarrow</tex> s.finish
Находим первый трапецоид <tex>\Delta_{0}</tex>
<tex>\Delta_{temp}</tex>
while q справа от rightp(<tex>\Delta_{0}</tex>)
if <tex>\Delta_{0}</tex> ниже <tex> s_{i} </tex>
<tex>\Delta_{temp}</tex> нижний правый сосед <tex>\Delta_{0}</tex>
else
<tex>\Delta_{temp}</tex> верхний правый сосед <tex>\Delta_{0}</tex>
Модифицируем <tex>\Delta_{0}</tex>
<tex>\Delta_{0} \leftarrow \Delta_{temp}</tex>
==Случай коллизии==
Рассмотрим момент, когда мы мы строим карты. Мы должны добавить очередной отрезок.
Предположим, левый конец отрезка лежит на одной вертикале вертикали с уже добавленной в карту точкой <tex> p </tex>.
Скажем, что наша точка лежит правее, чем та, которая уже есть. В случае, если мы попали на уже созданный отрезок, мы скажем, что находимся, например, ниже его.
==Асимптотика==
===Запрос===
Предположим , у нас есть запрос на локализацию точки <tex>q</tex>. Время, затраченное, на этот запрос , будет линейно зависеть от глубина глубины графа.
При добавлении в карту очередного отрезка(в дальнейшем, итерация алгоритма), глубина графа увеличивается максимум на 3. Из этого мы можем сделать простую оценку.
Наибольшее время на запрос, которое мы можем потратить {{---}} <tex>3n</tex>. Произойдет это в самом ужасном из самых ужасных случаев.
Как говорилось раньше, отрезки мы добавляем в случайном порядке, а потому, редко будет самый ужасный случай , и, с вероятностных точек зрения, время на запрос будет меньше.
Рассмотрим путь, пройденный точкой по графу. Каждый узел был создан на какой-то итерации цикла. Обозначим за <tex>X_i</tex> количество узлов, созданных на итерации <tex>i</tex>.
Таким образом <tex>P_i = P(\Delta_q(i) \ne \Delta_q(i - 1))</tex>.
Если эти два трапеецоида трапецоида не равны, значит , на i-ой итерации трапецоид <tex>\Delta_q(i)</tex> был одним из созданных при модификации.
Заметим, что все трапецоиды, созданные на этой итерации, были смежны текущему отрезку(<tex>s_i</tex>).
Значит , либо <tex>s_i = \operatorname{top} \Delta_i</tex> или <tex>\operatorname{bottom} \Delta_i</tex>, либо концы <tex>s_i = \operatorname{leftp} \Delta_i</tex> или <tex>\operatorname{rightp} \Delta_i</tex>.
Зафиксируем множество отрезков на <tex>i</tex>-ой итерации. Тогда состояние трапецоидов никак не будет зависеть от порядка добавленных отрезков.
Тогда, вероятность изменения трапецоида {{---}} это его вероятность исчезнуть, если удалится <tex>s_i</tex>.
Тогда переходим, к <tex>\operatorname{top} \Delta_i</tex> и т.п. так как мы уже говорили, что <tex>s_i</tex> будет определенной стороной при навигации.
<tex>\mathrm{Mem} = \mathcal{O}(n) + \sum^{n}_{i=1} E[k_i]</tex>
Используя вывод Введем новую функцию для трапецоида <tex> \Delta </tex> и отрезка s. Выделим множество <tex> S_i \in S </tex>. Пусть <tex> s \in S_i </tex> и <tex> \Delta \in T(S_i) </tex>. <tex> \delta(\Delta, s) </tex> равна 1, если при удалении <tex> s </tex> из предыдущей части получаем<tex> S_i </tex> <tex>, \Delta </tex> удалится, что иначе <tex> \delta </tex> равна 0. <tex>E[k_i] = \le frac{1}i \fracsum^{}_{s \mathcalin S_i} \sum^{O}_{\Delta \in T(iS_i)} \delta(\Delta, s)\le \frac{4|T(S_i|}i = \mathcal{O}(1)</tex>
А тогда <tex>\mathrm{Mem} = \mathcal{O}(n)</tex>
Удаляем это множество из карты и добавляем новые узлы появившиеся из-за <tex>s_i</tex> в поисковой структуре
Аналогично для просто карты
 
===Поиск трапецоидов, которых пересекает отрезок===
 
LookforTrapezoid(<tex>s_i</tex> - segment)
Запоминаем левый и правый конец <tex>s_i</tex>
Делаем запрос на левый конец в карте.
j <tex>\leftarrow</tex> 0;
while q <tex>\in</tex> правый от rightp(трапецоид_j)
do if rightp(трапецоид_j) над <tex>s_i</tex>
then ставим трапецоид_(j+1) нижним правым соседом трапецоид_j.
else ставим трапецоид_(j+1) верхним правым соседом трапецоид_j.
j <tex>\leftarrow</tex> j+1
==Ссылки==
[http://graphics.stanford.edu/courses/cs268-09-winter/ Lecture notes from stanford, Seidel]
 
[[Категория: Вычислительная геометрия]]
Анонимный участник

Навигация