Найти наименьший нерегулярный многоугольник из комбинации вершин (Performance Critical)
Мне нужно найти нерегулярный многоугольник с наименьшей площадью поверхности из нескольких вершин на двумерной плоскости.
Нет, это не домашнее задание. Хотя мне жаль, что я не вернулся в школу прямо сейчас.
Существуют некоторые требования относительно того, как можно построить многоугольник. Скажем, у меня есть 3 разных типа вершин (красный, зеленый, синий), построенный на сетке 8x8. Мне нужно сканировать все вершины в этой сетке, удовлетворяющие требованию красного, зеленого, синего комбинаций, и выбрать один с наименьшей площадью поверхности.
Получение площади поверхности неправильного многоугольника достаточно просто. Я в основном обеспокоен эффективностью эффективного сканирования всех возможных комбинаций.
См. изображение ниже для примера. Все три типа используются для создания полигонов, но один из них имеет наименьшую площадь поверхности и является моей целью.
![enter image description here]()
Этот сценарий упрощен по сравнению с тем, что я пытаюсь прототип. Многоугольники будут построены из десятков, если не сотен вершин, а сетка будет намного больше. Кроме того, это будет процесс, выполняемый 24/7.
Я думал, что, возможно, я должен организовать вершины по типу и разбить их на отдельные массивы. Затем просто перебирайте массивы многоуровневым способом, чтобы вычислить площадь поверхности всех комбинаций. Однако этот подход представляется расточительным.
Ответы
Ответ 1
Вот версия, основанная на ветке и грани, с некоторыми расцветами.
1) Разделите сетку на квадрат, с аннотациями в узлах, как это необходимо для остальных.
2) Найдите наименьший node в квадратном дереве, который имеет один из каждого типа node. Это дает вам начальное решение, которое должно быть как минимум достаточным для ускорения остальной части поиска.
3) Сделайте рекурсивный поиск, который принимает все возможные ветки, где я говорю "догадываться", сначала выбирая наиболее перспективных кандидатов, если применимо:
3a) Угадайте вершину наименьшего общего типа.
3b) Используя относительное расположение точек в квадратном дереве, чтобы упорядочить ваши догадки, угадайте вершину следующего наименее общего типа, чтобы угадать их в порядке возрастания расстояния от исходной точки...
3z) у вас есть полный набор вершин.
На каждом шаге 3? у вас есть частичный набор вершин, который, как я полагаю, дает вам нижнюю границу области любого полного решения, включая эти вершины (это область внутри выпуклой оболочки вершин?). Вы можете отказаться от каких-либо частичных решений, которые уже по крайней мере столь же велики, как и самые большие решения. Если вы можете жить с ответом, который является X% неточным, вы можете отказаться от любых частичных решений, которые находятся в пределах X% от самого большого решения. Надеюсь, это позволит вырезать дерево возможностей, в которые вы перемещаетесь (3) достаточно далеко, чтобы сделать его доступным.
Ответ 2
Как насчет выбора цвета с наименьшим количеством вершин и проверки для каждого ближайшего соседства, если в нем нет других цветов, увеличьте размер трафарета (выберите следующее кольцо вокруг вершины) и снова проверьте, Пока хотя бы одна из вершин имеет все остальные цвета в текущем трафарете. Если их несколько, вам просто нужно сравнить их (простое минимальное сокращение), чтобы найти самый маленький.
Ответ 3
Здесь, как найти наименьший треугольник во времени O (n 2 log n). Возможно, это будет полезно для вас.
Идея высокого уровня - использовать вращающуюся линию развертки. Во все времена мы сохраняем порядок синих точек вдоль оси, перпендикулярной линии развертки, в двоичном дереве поиска. Когда линия развертки параллельна линии, проходящей через красно-зеленую пару, мы используем BST, чтобы найти голубую точку, ближайшую к красно-зеленой линии.
Как всегда, мы используем симуляцию развертки, управляемую событиями. Для каждой красно-зеленой пары сделайте один вид события для своего угла. Для каждой пары синих точек сделайте O (1) другого вида событий, когда изменяется их относительный порядок. Сортировка всех событий и поворот рукоятки.
Ответ 4
Если мы уже нашли область A
, мы можем сузить поиск.
Площадь треугольника B*h
(высота базового раз).
Если вы найдете две точки, то B
- расстояние между ними.
Затем мы можем искать точку, которая не превосходит A/B
(B*h < A => h < A/B
) расстояние от этой линии. Это то же самое, что и поиск между двумя линиями, параллельными двум уже имеющимся точкам, которые смещены A/B
и -A/B
.
Это должно привести к сложности O(n^2*k)
, где k - ширина или высота вашей сетки.
Если вы не извлечете координаты, вы должны выполнить поиск O(k^5)
, который по крайней мере лучше, чем O(k^6)
, вам нужно было сделать это раньше.
Еще один анализ: если p - вероятность того, что ячейка содержит вершину, тогда сложность: O(k^2p(k^2p(kp))) = O(k^5p^3)
.
Если p=n/k^2
, где n
- число узлов, то получим O(n^3/k)
.