Подтвердить что ты не робот

Разложение на выпуклые многоугольники

Этот вопрос немного связан. Я написал алгоритм для разбиения простого многоугольника на выпуклые субполигоны, но теперь у меня возникают проблемы с доказательством того, что он не оптимален (т.е. минимальное число выпуклых многоугольников с использованием точек Штейнера (добавлены вершины)). Мой профессор непреклонен, что это невозможно сделать с помощью жадного алгоритма, такого как этот, но я не могу придумать контрпример.

Итак, если кто-то может доказать, что мой алгоритм является субоптимальным (или оптимальным), я был бы признателен.

Самый простой способ объяснить мой алгоритм с картинками (это из более ранней субоптимальной версии)

То, что мой алгоритм делает, расширяет сегменты линии вокруг точки я до тех пор, пока не достигнет точки на противоположном краю.

Если в этом диапазоне нет вершины, он создает новую (красную точку) и соединяется с ней:

Если в диапазоне есть одна или несколько вершин, она соединяется с ближайшей. Обычно это приводит к разложению с наименьшим числом выпуклых многоугольников:

Однако в некоторых случаях он может выйти из строя - на следующем рисунке, если сначала произойдет подключение средней зеленой линии, это создаст дополнительный ненужный многоугольник. Для этого я предлагаю двойную проверку всех ребер (диагоналей), которые мы добавили, и убедитесь, что они все еще необходимы. Если нет, удалите его:

В некоторых случаях, однако, этого недостаточно. См. Этот рисунок:

Замена a-b и c-d на a-c даст лучшее решение. В этом случае, однако, нет ребер для удаления, поэтому это создает проблему. В этом случае я предлагаю порядок предпочтения: при выборе вершин для соединения рефлекторной вершины, он должен выбрать вершину с наивысшим приоритетом:

самая низкая) ближайшая вершина

med) ближайшая рефлекторная вершина

самый высокий) ближайший рефлекс, который также находится в зоне действия при работе назад (трудно объяснить) -

В этот рисунок, мы видим, что рефлекторная вершина 9 выбрала подключение к 12 (потому что она была самой близкой), когда она лучше соединиться с 5. Обе вершины 5 и 12 находятся в диапазоне, определенном расширенными сегментами линии 10-9 и 8-9, но вершине 5 следует отдать предпочтение, поскольку 9 находится в пределах диапазона, заданного 4-5 и 6-5, но НЕ в диапазоне, заданном 13-12 и 11-12. то есть край 9-12 устраняет рефлекторную вершину в точке 9, но НЕ удаляет рефлекторную вершину в точке 12, но может удалять рефлекторную вершину в точке 5, поэтому предпочтение следует отдавать 5.

Возможно, что ребро 5-12 будет по-прежнему существовать с этой модифицированной версией, но его можно удалить во время последующей обработки.

Есть ли случаи, которые я пропустил?


Псевдокод (по просьбе Джона Фэминеллы) - этого не хватает битов под рисунками 3 и 5

assume vertices in `poly` are given in CCW order
let 'good reflex' (better term??) mean that if poly[i] is being compared with poly[j], then poly[i] is in the range given by the rays poly[j-1], poly[j] and poly[j+1], poly[j]

for each vertex poly[i]
    if poly[i] is reflex
        find the closest point of intersection given by the ray starting at poly[i-1] and extending in the direction of poly[i] (call this lower bound)
        repeat for the ray given by poly[i+1], poly[i] (call this upper bound)

        if there are no vertices along boundary of the polygon in the range given by the upper and lower bounds
            create a new vertex exactly half way between the lower and upper bound points (lower and upper will lie on the same edge)
            connect poly[i] to this new point
        else
            iterate along the vertices in the range given by the lower and upper bounds, for each vertex poly[j]
                if poly[j] is a 'good reflex'
                    if no other good reflexes have been found
                        save it (overwrite any other vertex found)
                    else
                        if it is closer then the other good reflexes vertices, save it
                else
                    if no good reflexes have been found and it is closer than the other vertices found, save it
            connect poly[i] to the best candidate
        repeat entire algorithm for both halves of the polygon that was just split
// no reflex vertices found, then `poly` is convex
save poly

Оказывается, есть еще один случай, который я не ожидал: [Рисунок 5]

Мой алгоритм попытается подключить вершину 1 к 4, если я не добавлю еще одну проверку, чтобы убедиться, что она может. Поэтому я предлагаю набивать все "в диапазоне" в очередь приоритетов, используя указанную выше схему приоритетов, а затем принимать наивысший приоритет, проверить, может ли он подключиться, если нет, вытащить его и использовать следующий. Я думаю, что это делает мой алгоритм O (r n log n), если я его оптимизирую правильно.


Я собрал веб-сайт, который свободно описывает мои выводы. Я, как правило, перемещаю вещи вокруг, поэтому получаю его, пока он горячий.

4b9b3361

Ответ 1

Я считаю, что обычная пятиконечная звезда (например, с чередующимися точками, имеющими коллинеарные сегменты) является контрпримером, который вы ищете.

Изменить в ответ на комментарии

В свете моего пересмотренного понимания, пересмотренный ответ: попробуйте острую пятиконечную звезду (например, один с достаточно узкими рычагами, у которых только три точки, составляющие руку, противоположную точке рефлекса, над которой вы работаете, находятся в пределах диапазона, который считается "хорошим" рефлекторные точки "). По крайней мере, работая над ним на бумаге, кажется, дает больше, чем оптимальный. Однако окончательное чтение вашего кода вызывает у меня вопрос: что вы подразумеваете под" ближайшим" (т.е. Ближе всего к чему)?

Примечание

Несмотря на то, что мой ответ был принят, это не тот пример, который мы изначально думали. Как отмечает @Mark в комментариях, он идет от четырех до пяти точно в то же время, что и оптимальный.

Флип-флоп, флип-флоп

По мере дальнейшего размышления, я думаю, что я был прав в конце концов. Оптимальную оценку четырех можно сохранить в острой звезде, просто убедившись, что одна пара рук имеет коллинеарные ребра. Но алгоритм находит пять, даже с исправлением.

Я получаю это:

удаление мертвой ссылки ImageShack

Когда оптимальным является следующее:

удаление мертвой ссылки ImageShack

Ответ 3

Я думаю, что ваш алгоритм не может быть оптимальным, потому что он не использует какой-либо показатель оптимальности. Вы используете другие показатели, такие как "ближайшие" вершины, и проверяете "необходимые" диагонали.

Чтобы управлять клином между вашим и оптимальным алгоритмом, нам нужно использовать этот пробел, ища формы с близкими вершинами, которые будут плохо разлагаться. Например (игнорируйте строки, я нашел это на intertubenet):

вогнутый многоугольник, который формирует форму G или U http://avocado-cad.wiki.sourceforge.net/space/showimage/2007-03-19_-_convexize.png

У вас нет защиты от самой центральной точки, связанной с вогнутым "зазором", который является внешним по отношению к многоугольнику.

Ваш алгоритм также довольно сложный и может переусердствовать - как сложный код, вы можете найти в нем ошибки, потому что сложный код делает сложные предположения.

Рассмотрим более обширный начальный этап, чтобы разбить форму на более простые формы - например, треугольники - и затем итеративный или генетический алгоритм для их рекомбинации. Вам понадобится такая сцена, чтобы в любом случае объединить любые ненужные различия между вашими выпуклыми полисами, и к тому времени вы, возможно, ограничили свои возможные разложения только субоптимальными решениями.

Угадайте что-то вроде:

  1. разложить на треугольники
  2. недетерминированно генерирует ряд рекомбинаций
  3. вычислить метрику качества (количество полисов)
  4. выберите лучший x% рекомбинаций
  5. частично разложите каждый, используя треугольники, и создайте новый набор рекомбинаций
  6. повторите с 4 до тех пор, пока не будет достигнута определенная степень сходимости

Ответ 4

но вершине 5 следует отдать предпочтение, потому что 9 находится в пределах диапазона, заданного значениями 4-5 и 6-5

Что бы вы сделали, если 4-5 и 6-5 были еще более выпуклыми, чтобы 9 не лежали в пределах их диапазона? Тогда по вашим правилам правильнее было бы подключить 9 к 12, потому что 12 - ближайшая рефлекторная вершина, которая была бы субоптимальной.

Ответ 5

Нашел это:( Они на самом деле совершенно очевидны.


* dead imageshack img *

Четыре листа клевера не будут оптимальными, если точки Штейнера разрешены... красные вершины могли быть связаны.


* dead imageshack img *

Он даже не будет оптимальным без очков Штейнера... 5 может быть подключен к 14, устраняя необходимость в 3-14, 3-12 и 5-12. Это могло быть два полигона лучше! Ой!