SO,
Проблема
У меня есть вопрос об алгоритме определения того, связаны ли две точки на 2D-плоскости. У меня есть:
- Массив 2D-линий. Каждая строка ограничена двунаправленной точкой начала конца. Каждая точка представляет собой простой массив из двух элементов
[x,y]
- то есть каждая строка выглядит как['start'=>[X0, Y0], 'end'=>[X1, Y1]]
. Пусть этот набор строк будет называтьсяL
. Линии могут принадлежать друг другу (т.е. Могут быть частью другого), их можно пересечь только одной точкой e.t.c. - то есть нет ограничений для них на двумерной плоскости. Но строка не может быть точкой - то есть начало строки не может быть равно концу строки. - Две точки
S
иE
, то есть массивы[Xs, Ys]
и[Xe, Ye]
Теперь все строки из L
рисуются на плоскости. Затем также рисуются S
и E
, и мне нужно ответить на вопрос: может ли E быть достигнуто из S без пересечения любых строк в L? И, если быть более конкретным - какой алгоритм будет оптимальным? Под "может быть достигнуто" я имею в виду, что есть путь на плоскости от S
до E
без пересечения любой строки из L
- и, быть может, это может быть что угодно, а не только строка.
Пример
- как видите, в образце S
и E
не подключены. Также в образце есть случай, когда одна строка полностью принадлежит другому (серые и фиолетовые линии) - и случай, когда одна строка имеет начало/конец на другой строке (зеленые и розовые линии).
Мой подход
В настоящее время для этого я имею недетерминированный полиномиальный (NP) алгоритм. Это шаги:
- Найти все пересечения для каждой пары линий.
- Создайте новый набор строк из точек первого шага. Если две линии имеют одно пересечение, то в начале каждой новой строки будут четыре новые линии с точкой пересечения - или это могут быть 3 новые строки, если первая строка имеет начало/конец второй строки - или это может быть 2 новых строки, если первая строка имеет начало/конец, точно соответствует началу/концу второй линии. То есть:
поэтому 1-й случай приведет к 4 новым строкам, 2-4 случаям в 3 новых строках и 5 случаям в 2 новых строках. (строки [A, B]
и [C, D]
)
- Далее, в строках, начиная с 2-го шага, я ищу все полигоны. Многоугольник - это замкнутое линейное множество (т.е. Оно содержит замкнутую часть области)
- Я определяю для подмножества
S
таких многоугольников, которые содержатS
. Для этого я использую простой алгоритм - подсчет числа пересечений с краями многоугольника и некоторой строки изS
на внешнюю плоскость (если он нечетный, тоS
находится внутри многоугольника, а если он четный - затем снаружи). Это алгоритм ray-casting. Тогда я делаю это дляE
- Теперь, когда у меня есть многоугольники, установленные для
S
иE
, я просто сравниваю оба набора. Если они равны, тоE
может быть достигнуто отS
и не может быть - в противном случае.
Почему этот NP?
Ответ прост: на 3-м шаге я выполняю поиск целых всех циклов в 2D-графике. Поскольку проблема нахождения максимальной/минимальной длины петли, если NP, то моя тоже (потому что я могу получить максимальную/минимальную длину цикла просто с настройкой набора циклов сортировки). Хорошая информация об этом находится здесь.
Вопрос
Поскольку мое текущее решение NP, я хочу знать - может быть, мое решение проблемы - перебор? То есть может быть, есть более простое решение, которое приведет к полиномиальному времени?