凸壳中最大的三角形

时间:2013-08-24 20:56:30

标签: c algorithm computational-geometry

问题已经得到解答,但我面临的主要问题是理解其中一个答案。

https://stackoverflow.com/a/1621913/2673063

以下算法如何O(n)

它表示为 通过首先对点进行排序/计算凸包(在O(n log n)时间内),如果需要,我们可以假设我们有凸多边形/船体,其点按照它们在多边形中出现的顺序循环排序。调用点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)。这个点C将是那些固定A和B最大化面积(ABC)的点。(换句话说,函数Area(ABC)是C的函数的单峰值。)

接下来,如果增加面积,则前进B(不改变A和C)。如果是这样,再次按上述方式推进C.然后如果可能的话再次前进B等。这将给出最大区域三角形,其中A作为顶点之一。 (到这里的部分应该很容易证明,并且简单地为每个A单独执行此操作将给出O(n2)。但请继续阅读。)现在再次推进A,如果它改善了区域等。 虽然这有三个“嵌套”循环,但请注意B和C总是向前推进,并且它们总共最多前进2n次(类似A最多前进n次),因此整个过程在O(n)时间内运行

2 个答案:

答案 0 :(得分:3)

作为问题主题的the answer的作者,我觉得有必要对O(n)运行时进行更详细的解释。


首先,作为一个例子,这里是一篇文章的图,显示了算法的前几个步骤,对于特定的样本输入(12-gon)。首先,我们从A,B,C开始,作为三个连续的顶点(图中的步骤1),只要面积增加(步骤2到6)就前进C,然后前进B,依此类推。

Sample run

上面带有星号的三角形是“锚定的局部最大值”,即最适合给定A的三角形(即,推进C或B会减小面积)。


至于运行时为O(n):让B的“实际”值按其增加的次数而忽略环绕,为nB,类似地,C为nC。 (换句话说,B = nB % nC = nC % n。)现在,请注意,

  1. (“B在A之前”)无论A的值如何,我们都有A≤nB< A + n

  2. nB总是在增加

  3. 因此,当A从0变为n时,我们知道nB仅在0和2n之间变化:它最多可以增加2n次。同样nC。这表明算法的运行时间与A,B和C的总次数成正比,由O(n)+ O(2n)+ O(2n)限定,即O(n) )。

答案 1 :(得分:0)

这样想:A, B, C中的每一个都是在任何给定时刻指向凸包的一个元素的指针。由于算法递增它们的方式,它们中的每一个将最多指向凸包的每个元素一次。因此,每个元素都将迭代O(n)个元素的集合。它们将永远不会被重置,一旦其中一个元素通过元素,它将不会再次传递该元素。

由于有3个指针(A, B, C),因此我们有时间复杂度3 * O(n) = O(n)

修改

由于代码在提供的链接中显示,听起来可能不是O(n),因为BC环绕数组。然而,根据描述,这种环绕听起来并不是必要的:在看到代码之前,我想象了停止BC过去n的推进的方法。在这种情况下,它肯定是O(n)。然而,当代码出现时,我不确定。

由于某些数学原因,BC仍然只能在整个算法中迭代O(n)次,但我无法证明这一点。我也不能证明不回滚是正确的(只要你处理索引越界错误)。