Когда вы имеете дело с проблемами пространственного индексирования, я действительно рекомендую начинать с пространственного хэша или моего личного фаворита: простой старой сетки.
... и сначала поймите его недостатки, прежде чем переходить к древовидным структурам, которые допускают разреженные представления.
Одним из очевидных недостатков является то, что вы могли бы тратить память на множество пустых ячеек (хотя прилично реализованная сетка не должна требовать более 32 бит на ячейку, если у вас нет фактически вставляемых миллиардов узлов). Другая причина в том, что если у вас есть элементы среднего размера, которые больше, чем размер ячейки, и часто занимают, скажем, десятки ячеек, вы можете тратить много памяти, вставляя эти элементы среднего размера в гораздо большее количество ячеек, чем в идеале. Аналогично, когда вы делаете пространственные запросы, вам, возможно, придется проверять больше ячеек, иногда гораздо больше, чем в идеале.
Но единственное, что нужно сделать с сеткой, чтобы сделать ее как можно более оптимальной по отношению к определенному входу, - это то cell size
, что вам не нужно много думать и возиться, и именно поэтому это моя структура данных перехода. для задач пространственного индексирования, пока я не найду причины не использовать его. Это очень просто реализовать и не требует от вас возиться с чем-то большим, чем один ввод времени выполнения.
Вы можете получить много от простой старой сетки, и я на самом деле обошел множество реализаций quad-tree и kd tree, используемых в коммерческом программном обеспечении, заменив их простой старой сеткой (хотя они не обязательно были лучшими из реализованных). , но авторы потратили намного больше времени, чем те 20 минут, которые я потратил, чтобы навести порядок). Вот небольшая небольшая вещь, которую я подхватил, чтобы ответить на вопрос в другом месте, используя сетку для обнаружения столкновений (даже не очень оптимизированную, всего несколько часов работы, и мне пришлось потратить большую часть времени, изучая, как работает поиск пути, чтобы ответить на вопрос и я также впервые реализовал обнаружение столкновений такого рода):
Другой недостаток сеток (но они являются общими слабостями для многих структур пространственного индексирования) заключается в том, что если вы вставите много совпадающих или перекрывающихся элементов, например много точек с одинаковым положением, они будут вставлены в одну и ту же ячейку (и). ) и ухудшать производительность при прохождении этой ячейки. Точно так же, если вы вставите много массивных элементов, которые намного больше, чем размер ячейки, они захотят вставить их в кучу ячеек и использовать много-много памяти и уменьшить время, необходимое для пространственных запросов по всем направлениям. ,
Однако указанные выше две непосредственные проблемы с совпадающими и массивными элементами фактически проблематичны для всех структур пространственного индексирования. Простая старая сетка фактически обрабатывает эти патологические случаи немного лучше, чем многие другие, поскольку, по крайней мере, она не хочет рекурсивно делить клетки снова и снова.
Когда вы начинаете с сетки и прокладываете путь к чему-то вроде квад-дерева или дерева KD, тогда основная проблема, которую вы хотите решить, - это проблема с элементами, вставляемыми в слишком много ячеек, имеющими слишком много ячеек, и / или нужно проверить слишком много ячеек с этим типом плотного представления.
Но если вы думаете о квад-дереве как о оптимизации по сеткетогда для конкретных случаев использования это все еще помогает думать об идее «минимального размера ячейки», чтобы ограничить глубину рекурсивного подразделения узлов четырехугольника. Когда вы это сделаете, наихудший сценарий четырехъядерного дерева все равно будет разлагаться до плотной сетки на листьях, только менее эффективно, чем сетка, поскольку для ее перехода от корня к ячейке сетки потребуется логарифмическое время. постоянное время. Тем не менее, размышления об этом минимальном размере ячейки позволят избежать сценария бесконечного цикла / рекурсии. Для массивных элементов есть также несколько альтернативных вариантов, таких как свободные четырехугольные деревья, которые не обязательно разделяются равномерно и могут иметь AABB для дочерних узлов, которые перекрываются. BVH также интересны как структуры пространственной индексации, которые не делят свои узлы равномерно. Для совпадающих элементов против древовидных структур, главное - просто наложить ограничение на подразделение (или, как другие предложили, просто отклонить их или найти способ обращаться с ними так, как будто они не влияют на уникальное количество элементов в листе при определении того, когда лист следует подразделить). Дерево Kd также может быть полезно, если вы ожидаете входные данные с большим количеством совпадающих элементов, поскольку вам нужно учитывать только одно измерение при определении того, должен ли узел разделяться по медиане.