Подсказка: эта проблема в основном двойственная к проблеме выпуклой оболочки .
Решение: если вы обрабатываете каждую линию y=ax+b
как точку (a,b)
и добавляете дополнительную «точку» в (0, -infinity)
, вы должны иметь возможность вставить ее в любой алгоритм 2D выпуклой оболочки и получить правильное решение .
Примечание. И наоборот, любое решение этой проблемы также может быть использовано для построения двумерного алгоритма выпуклой оболочки с той же O ().
Редактировать: просьба доказать это ...
Чтобы точка (x,y)
находилась выше определенной линии y=ax+b
, имеет место неравенство ax - y + b > 0
.
Это неравенство также эквивалентно точке (-a,b)
, находящейся выше линии (b)=x(-a)+y
, где x - наклон, а y - точка пересечения.
Эта двойственность позволяет нам рассматривать точки как линии, а линии как точки: любое доказательство или алгоритм на точках и линиях можно сопоставить в одинаково допустимую линию с обратными линиями и точками.
В этом случае: выпуклая оболочка набора двумерных точек определяет «крайние» точки, которые не являются выпуклыми комбинациями других, а также линии между последовательными крайними точками. Соответственно, двойная версия выпуклой оболочки определяет те «крайние» линии, которые не являются выпуклыми комбинациями других, а также точки пересечения между последовательными крайними линиями. Это конверт данного набора линий.
Двойной из выпуклой оболочки дает вам как верхнюю, так и нижнюю огибающую набора входных линий. Поскольку вам нужен только верхний конверт ваших строк, вам нужно добавить строку ниже любой возможной обычной линии, чтобы исключить нижний конверт. Кроме того, вы можете просмотреть решение и выбрать только пересечения с наклоном.
И наоборот, любое решение этой проблемы можно использовать для определения верхней выпуклой оболочки множества точек. Запуск его дважды, один раз для строк {(a, b)} и снова для строк {(-a, -b)}, даст вам полную выпуклую оболочку.