点数最多的三角形

时间:2018-10-27 11:07:01

标签: algorithm geometry time-complexity 2d polygon

给定2D点集,可以找到由这些点构成的三角形,其中包含了最多的点。

对此的残酷算法只是从每个可能的三元组构建三角形并检查它们包含多少个点,但是此解决方案的时间复杂度为O(n ^ 4)。

为获得最佳解决方案,我考虑过先找到这些点的凸包,然后在该包中以某种结构排列点,但是我无法弄清楚。

您对针对此类问题的最佳解决方案有任何想法吗?

1 个答案:

答案 0 :(得分:2)

在一组 n 个点中,有(n个选择3个)三角形,并使用蛮力检查每个点是否确实包含在每个三角形中具有O(n 4 )复杂度。给出一些集合大小的实际示例:

points:            100              1,000                   10,000
triangles:     161,700        166,167,000          166,616,670,000
checks:     15,684,900    165,668,499,000    1,665,666,849,990,000

下面是一些几何构想;它们不能直接导致解决方案,但可以减少必须检查的三角形数量。

凸包的反例

首先,不能保证仅使用凸包上的点来提供最佳解决方案。考虑以下反例:

convex hull vs triangle

凸包是红色矩形。但是,如果我们使用其两个侧面和一个对角线来形成三角形,则对角线将切穿中心点簇,并省略一些点。即使我们仅使用矩形的1个或2个角,并在中心加上一个点,它也将始终切穿蓝色三角形并留下一些点。在凸包上没有任何点的蓝色三角形实际上是最佳解决方案。

三角形中包含的三角形

如果考虑一个三角形 abc ,其中包含三个点 d e f ,那么三角形 def 不能是包含最多点的三角形,因为三角形 abc 至少包含三个点。由 abc def 的点组合而成的三角形(如 abd )所包含的点也少于 abc

这意味着找到一个三角形和其中包含的一些点,可以让您丢弃许多三角形。在接下来的段落中,我们将使用这种想法从必须检查的地方丢弃尽可能多的三角形。

展开三角形

如果我们考虑由三个随机选择的点 a b c (按顺时针命名)组成的三角形,然后检查其他所有点是否都位于线 | ab | | bc | | ca | 的右侧,则这些点是分为7个区域:

partitioning into 7 zones

如果我们用相邻彩色区域中的一个点替换三角形的一个角点,例如点 a 的区域LRL,我们得到了一个较大的三角形,其中包含三角形 abc 。如果我们从区域LRL,LLR和RLL中随机选择三个点,我们可以像这样扩展三角形:

expanding a triangle

然后我们可以使用这个新的三角形 a'b'c'再次对点进行分区(可以将区域RRR中的点添加到新区域RRR中,而无需检查),并再次扩展三角形只要在区域LRL,LLR或RLL中至少有一个点。

final expansion

如果我们在扩展三角形内捕获了足够的点,我们现在可以使用蛮力算法,但是跳过在扩展三角形 a'b“ c'之外没有点的任何三角形

如果我们没有捕捉到足够的分数来使之可行,我们可以再尝试三个随机点。但是请注意,您不应使用包含在多个三角形中的点的并集;三个点(每个点包含在另一个三角形中,但不在同一个三角形中)仍然可以是包含最多点的三角形。

分多个步骤排除三角形

我们可以重复选择一个随机三角形,最大程度地扩展它,然后标记由三角形上或内部的三个点组成的三角形,然后将其从检查中排除。这将需要为所有可能的三角形存储一个布尔值,例如在3D位阵列中,因此仅适用于设置几千个点。

为简化起见,我们可以使用许多随机选择的三角形,或由凸包上的点组成的三角形,或在x或y方向上排列得很远的点,而不是扩展随机的三角形,或者...但是这些方法中的任何一种都只会帮助我们找到可以排除的三角形,它们本身不会给我们提供最佳(甚至足够好)的三角形。