Вот такой подход, который я считаю многообещающим. Создайте сопряжение красных и синих точек (R1, B1), (R2, B2), .. (Rn, Bn). Затем перейдите в список и для каждого (Rj, Bj) проведем прямую Rj - Bj. Если эта линия пересекает любую другую линию Ri-Bi, уже нарисованную, «пересечь» эти строки, заменив их Ri-Bj и Rj-Bi (фактически изменив вашу «плохую» картину на вашу «хорошую» картинку).
Вы должны проверить, пересекаются ли эти новые линии с любыми другими существующими линиями, и в этом случае вы неоднократно выполняете те же «свопы» и «проверку пересечения», пока не будет больше пересекающихся линий. Затем вы затем присоединяетесь к паре после (Rj, Bj) и так далее, пока не закончите.
Как отмечено в my other answer, сопряжение красных и синих точек, которое сводит к минимуму общую длину края, также будет без перекрестков. В подходе, указанном в этом ответе, обратите внимание, что каждый раз, когда вы «пересекаете» края, вы уменьшаете общее количество всех длин кромок. Алгоритм, скорее всего, не достигнет конфигурации сопряжения с минимальной суммой длин ребер. Однако тот факт, что общая длина ребер уменьшается при каждом подкачке, означает, что алгоритм всегда будет заканчиваться (т. Е. Вы не попадете в повторяющуюся последовательность реберных свопов).
Я согласен с вашей идеей. Моя первая мысль заключалась в том, чтобы удалить линию (по внешней линии) один за другим с помощью выпуклого корпуса. , но если выпуклый корпус имеет тот же тип внешних точек, он потерпит неудачу. посмотрите на этот рисунок «http://s22.postimg.org/ce109t15t/image.png». , а затем, я пробовал, как вы, метод деления и завоевания Однако в результате я не смог найти эффективную точку, которую можно разделить. – user2821655
Нахождение пары разделов может быть выполнено в O (nlogn) на самом деле. – user2782067