我想实现一个程序,将平面中n个点的集合S分为两个集合,以使两个集合的凸包的距离最大化。
应该在O(n ^ 3)中完成。
我有几个想法,但不确定它们是否正确:
1.想法:我将点按X排序,然后对每两个点求出距离,但前提是它们之间没有其他点。然后,我选择最左边的第一个点和最右边的第二个点(第一个点是第一个多边形的一部分,第二个是第二个多边形的一部分)。然后我找到点与线之间,线与线之间,线与点之间以及与点与点之间的距离(但是我已经知道了)。这就是我找到最大距离的方法,然后通过Graham扫描创建凸包。
我对Y重复所有操作,因为最大距离可能在Y上,而不是X上。
2.想法:我按X对点进行排序,然后为前3个创建凸包,并为其他点创建另一个凸包。然后找到这两个船体之间的最小距离。我保存距离,如果该距离大于在覆盖并记住多边形之前保存的距离。最后一步是第二个凸包仅剩3个点。然后,我对Y执行所有这些步骤。
你们如何看待我的想法?您是否有任何改进或其他更好的主意?
答案 0 :(得分:3)
O(N ^ 3)。首先查看此内容:https://gamedevelopment.tutsplus.com/tutorials/collision-detection-using-the-separating-axis-theorem--gamedev-169
现在,如果两个凸包之间的距离为 x ,则存在一个轴,这些包中的点沿该轴以 x 隔开。相反,如果沿任意轴的点的投影之间存在 x 间隙,则该间隙两侧的点的凸包将至少间隔 x < / strong>。
因此,如果您发现点之间的间隙最大的轴,则该间隙两侧的点组将在其凸包之间具有最大的距离。
好消息是,只有 O(N ^ 2)个可能的最佳轴。两个凸包之间的距离将是包中两个点(角)之间的距离,或者是一个点与另一条线之间的距离。在第一种情况下,相应的分隔轴将沿着任一壳体中两点之间的直线。在第二种情况下,分离轴将垂直于一个船体中的直线。无论哪种方式,轴都垂直或平行于两点之间的线,并且只有 O(N ^ 2)个方向。
因此,您可以尝试所有可能的方向,对每个轴上的点进行排序,并找出它们之间的最大间隙。总时间是... O(N ^ 3 * log N)。
为了将其降低到 O(N ^ 2),您必须将每个轴的排序降低到 O(N)。事实证明,这实际上没有问题。如果沿坡度顺序浏览所有可能的轴方向,则沿途看到的反转总数(成对的点改变顺序)为 O(N ^ 2)。如果使用插入排序对每个轴重新求点,那么它将进行的总移动量与它进行的反转次数成正比。总共是 O(N ^ 2)。将其与每个方向的线性扫描部分相加即可得出 O(N ^ 3)的总功。