Квадродеревья — различия между версиями
Gromak (обсуждение | вклад) (Новая страница: «<div style="background-color: #ABCDEF; font-size: 16px; font-weight: bold; color: #000000; text-align: center; padding: 4px; border-style: solid; border-width: 1p...») |
Gromak (обсуждение | вклад) |
||
Строка 27: | Строка 27: | ||
Квадродерево глубины <tex>d</tex> для <tex>n</tex> точек содержит <tex>O(d \cdot n)</tex> вершин и может быть построено за <tex>O(d \cdot n)</tex>. | Квадродерево глубины <tex>d</tex> для <tex>n</tex> точек содержит <tex>O(d \cdot n)</tex> вершин и может быть построено за <tex>O(d \cdot n)</tex>. | ||
|proof= | |proof= | ||
− | Поскольку каждая внутренняя вершина имеет четырёх детей, то суммарное число листьев будет <tex>3i + 1</tex>, где <tex>i</tex> {{---}} число внутренних вершин. Поэтому достаточно доказать | + | Поскольку каждая внутренняя вершина имеет четырёх детей, то суммарное число листьев будет <tex>3i + 1</tex>, где <tex>i</tex> {{---}} число внутренних вершин. Поэтому достаточно доказать оценки лишь для внутренних вершин. |
Каждая внутренняя вершина содержит хотя бы одну точку в соответствующем ей квадрате. Заметим, что квадраты с одного уровня не пересекаются и полностью покрывают весь исходный квадрат (в котором <tex>n</tex> точек). Значит, число внутренних вершин одного уровня не может первосходить <tex>n</tex>. Из этого следует, что всего внутренних вершин <tex>O(d \cdot n)</tex>. | Каждая внутренняя вершина содержит хотя бы одну точку в соответствующем ей квадрате. Заметим, что квадраты с одного уровня не пересекаются и полностью покрывают весь исходный квадрат (в котором <tex>n</tex> точек). Значит, число внутренних вершин одного уровня не может первосходить <tex>n</tex>. Из этого следует, что всего внутренних вершин <tex>O(d \cdot n)</tex>. | ||
+ | |||
+ | При построении квадродерева наиболее длительная операция на каждом шаге {{---}} распределение точек по четвертям текущего квадрата. Таким образом, время, затрачиваемое на одну внутренню вершину, линейно зависит от числа точек в соответствующем ей квадрате. Как отмечалось выше, на одном уровне суммарно во всех внутренних вершинах не больше <tex>n</tex> точек, из чего следует доказываемая оценка. | ||
}} | }} | ||
+ | == Перечисление точек в произвольном прямоугольнике == | ||
+ | Пусть на вход подаётся некоторый прямоугольник <tex>M</tex>, для которого надо вернуть все точки из множества <tex>P</tex>, которые принадлежат этому прямоугольнику. | ||
+ | |||
+ | Алгоритм следующий: | ||
+ | * если мы лист, то просто проверяем, лежит ли наша точка в <tex>M</tex>, и возвращаем её, если да; | ||
+ | * иначе запускаемся от детей и возвращаем объединение всего того, что вернули дети. | ||
+ | |||
+ | Псевдокод можно посмотреть [http://en.wikipedia.org/wiki/Quadtree#Pseudo_code здесь]. Там немного по-другому (хранят не больше 4-х точек в каждой вершине дерева, а у нас подразумевается, что точки явно хранятся только в листьях), но в целом <tex>queryRange</tex> почти такой же. | ||
+ | |||
+ | Если совсем кратко, то запрос выглядит так: | ||
+ | <code> | ||
+ | if (P is a leaf) then | ||
+ | if (P.point in M) then | ||
+ | report P.point | ||
+ | for each child C of P do | ||
+ | if C.region intersects M then | ||
+ | QTree-RangeSearch(C, M) | ||
+ | </code> | ||
+ | |||
+ | [https://groups.google.com/forum/#!topic/uw.cs.cs240/MGfrsvKAiMA Тут] говорят, что работает за <tex>\theta (d + n)</tex>. Видимо, так и есть, но я пока не понял, как это обосновать, может показаться, что <tex>\theta (d \cdot n)</tex>. | ||
+ | |||
+ | Ну а вообще, можно делать по-тупому за <tex>O(n)</tex>, но, видимо, так обычно быстрее получается. | ||
== Литература == | == Литература == | ||
* ''van Kreveld, de Berg, Overmars, Cheong {{---}} Computational Geometry. Algorithms and Applications.'' Страница 309. | * ''van Kreveld, de Berg, Overmars, Cheong {{---}} Computational Geometry. Algorithms and Applications.'' Страница 309. |
Версия 16:16, 5 января 2014
Содержание
Определение и построение
Квадродерево — дерево, каждая внутренняя вершина которого содержит 4 ребёнка. Любому узлу квадродерева соответствует некоторый квадрат. Если внутренней вершине
соответствует какой-то квадрат , то её детям соответствуют четверти квадрата (см. картинку).Вообще говоря, квадродеревья могут быть использованы для разных целей и хранить разные данные, но нам они нужны для перечисления точек в произвольном прямоугольнике, соответственно, хранить в них будем какой-то набор точек.
Пусть дано множество точек
, для которого нужно построить квадродерево. Начнём с некоторого квадрата , содержащего все точки из . Если он не дан явно, его можно легко найти за линейное время от числа вершин. Пусть . Обозначим . Тогда:- если содержит не больше одной точки, то квадродерево состоит из одного листа, которому соответствует квадрат ;
- иначе корнем дерева делаем вершину , которой соответствует квадрат , а его дети — , и им соответствуют квадраты , , , . Затем таким же образом рекурсивно превращаем каждого ребёнка в квадродерево для множества точек, лежащих в соответствующем квадрате.
Леммы и теоремы
Сперва оценим глубину квадродерева. Если какие-то две точки лежат очень близко, то процесс построения может продолжаться очень долго, поэтому глубину невозможно оценить функцией от числа вершин.
Лемма: |
Глубина квадродерева для множества точек не превосходит , где — наименьшее расстояние между двумя точками из , а — сторона квадрата, с которого начинается построение квадродерева. |
Доказательство: |
Сторона квадрата на глубине | , очевидно, равна . Максимальное расстояние между двумя точками внутри квадрата достигается, когда они являются вершинами диагонали, то есть на глубине расстояние между любыми двумя точками в одном квадрате не превосходит . Поскольку внутренняя вершина квадродерева содержит хотя бы 2 точки в соответствующем ей квадрате, то , так как — минимальное расстояние между точками в . Отсюда следует, что . Значит, глубина любой внутренней вершины не превосходит , из чего следует утверждение леммы.
Размер дерева и время построения будут также зависеть и от
— мощности .Теорема: |
Квадродерево глубины для точек содержит вершин и может быть построено за . |
Доказательство: |
Поскольку каждая внутренняя вершина имеет четырёх детей, то суммарное число листьев будет , где — число внутренних вершин. Поэтому достаточно доказать оценки лишь для внутренних вершин.Каждая внутренняя вершина содержит хотя бы одну точку в соответствующем ей квадрате. Заметим, что квадраты с одного уровня не пересекаются и полностью покрывают весь исходный квадрат (в котором При построении квадродерева наиболее длительная операция на каждом шаге — распределение точек по четвертям текущего квадрата. Таким образом, время, затрачиваемое на одну внутренню вершину, линейно зависит от числа точек в соответствующем ей квадрате. Как отмечалось выше, на одном уровне суммарно во всех внутренних вершинах не больше точек). Значит, число внутренних вершин одного уровня не может первосходить . Из этого следует, что всего внутренних вершин . точек, из чего следует доказываемая оценка. |
Перечисление точек в произвольном прямоугольнике
Пусть на вход подаётся некоторый прямоугольник
, для которого надо вернуть все точки из множества , которые принадлежат этому прямоугольнику.Алгоритм следующий:
- если мы лист, то просто проверяем, лежит ли наша точка в , и возвращаем её, если да;
- иначе запускаемся от детей и возвращаем объединение всего того, что вернули дети.
Псевдокод можно посмотреть здесь. Там немного по-другому (хранят не больше 4-х точек в каждой вершине дерева, а у нас подразумевается, что точки явно хранятся только в листьях), но в целом почти такой же.
Если совсем кратко, то запрос выглядит так:
if (P is a leaf) then if (P.point in M) then report P.point for each child C of P do if C.region intersects M then QTree-RangeSearch(C, M)
Тут говорят, что работает за . Видимо, так и есть, но я пока не понял, как это обосновать, может показаться, что .
Ну а вообще, можно делать по-тупому за
, но, видимо, так обычно быстрее получается.Литература
- van Kreveld, de Berg, Overmars, Cheong — Computational Geometry. Algorithms and Applications. Страница 309.