一尘不染

除了蛮力搜索外,如何在凸包中找到最大的三角形

algorithm

给定一个凸多边形,我如何找到定义面积最大的三角形的3个点。

相关: 那个三角形的外接圆是否也将定义多边形的最小边界圆,这是真的吗?


阅读 301

收藏
2020-07-28

共1个答案

一尘不染

是的,您可以做得比蛮力要好得多。

通过蛮力,我假设您的意思是检查所有三重点,然后选择面积最大的那个。这在 O(n 3)时间内运行,但事实证明,不仅可以在O(n 2)内 而且可以在
O(n)时间内进行

[ 更新:
2017年发表的一篇论文通过示例显示O(n)解决方案不适用于特定类别的多边形。

通过在必要时首先对点进行排序/计算凸包(在O(nlogn)时间中),我们可以假定我们拥有凸多边形/包,其中点按在多边形中出现的顺序循环排序。调用点1、2、3,…,n。让(变量)点A,B和C分别从1、2和3开始(按循环顺序)。我们将移动A,B,C,直到ABC是最大面积三角形。(该想法类似于在计算[直径(最远对)时使用的旋转卡尺方法。
在A和B固定的情况下,只要三角形的面积增加,前进C(例如,初始时A = 1,B = 2,C前进C = 3,C =
4,…),面积(A,B,C)≤面积(A,B,C +
1)。对于固定的A和B,这一点C将是使Area(ABC)最大化的点。(换句话说,函数Area(ABC)是C的 单峰 函数)。

接下来,如果增加了面积,则前进B(不更改A和C)。如果是这样,请再次如上前进C。然后,如果可能的话,再次使B前进,以此类推。这将得到最大面积的三角形,其中A为顶点之一。

(到此为止的部分应该很容易证明,并且简单地对每个A单独执行此操作将得到O(n 2)算法。)

现在,如果可以改善面积,请再次前进A,依此类推。(这部分的正确性更加微妙:Dobkin和Snyder在他们的论文中提供了证明,但是最近的论文显示了一个反例。我还不了解。)

尽管这具有三个“嵌套”循环,但请注意,B和C总是前进“向前”,它们总共前进最多2n次(类似地,A最多前进n次),因此整个过程以O(n)的时间运行。

Python中的代码片段(转换为C应该很简单):

 # Assume points have been sorted already, as 0...(n-1)
 A = 0; B = 1; C = 2
 bA= A; bB= B; bC= C #The "best" triple of points
 while True: #loop A

   while True: #loop B
     while area(A, B, C) <= area(A, B, (C+1)%n): #loop C
       C = (C+1)%n
     if area(A, B, C) <= area(A, (B+1)%n, C): 
       B = (B+1)%n
       continue
     else:
       break

   if area(A, B, C) > area(bA, bB, bC):
     bA = A; bB = B; bC = C

   A = (A+1)%n
   if A==B: B = (B+1)%n
   if B==C: C = (C+1)%n
   if A==0: break

该算法已在Dobkin和Snyder的《
关于最大化和最小化某些几何问题的通用方法》(FOCS 1979)中得到了证明,并且上面的代码是其ALGOL-60代码的直接翻译。断断续续的结构表示歉意;应该可以将它们转换为更简单的while循环。

2020-07-28