我必须以最佳方式解决以下问题。
输入数据是:
我需要找到一种方法来隔离具有属性的多个圆圈而不是任何“好”圆圈,从前N个点放置在所选圆圈中或所选圆圈的边缘没有任何点。
点数和圆圈的数量级为100,000。每个点检查每个圆的明显解决方案具有复杂度O(N * M)和100,000个圆和100,000个点,在具有64位SSE3单精度代码的Core 2 Duo上花费大约15秒。我竞争的参考实现只需要大约0.1秒的相同数据。我知道参考实现是O(Nlog N + Mlog M)。
我想过以下列方式优化算法。制作2个点数据副本,并根据x坐标和y坐标对副本进行排序。然后只使用位于[(xc - r,yc - r)定义的方格中的点; (xc + r,yc + r)],其中(xc,yc)是“当前”圆的中心,半径为r。我可以使用二进制搜索在该间隔中找到点,因为现在我使用已排序的数据。这种方法的复杂性应该是O(Nlog N + Mlog ^ 2 N),实际上它比参考更快但仍然明显慢。
我或多或少知道参考实现的工作原理,但有些步骤我不明白。我将尝试解释到目前为止我所知道的事情:
坐标为(Xc,Yc)的圆的半径为:
那是因为(0,0)位于圆的边缘。
如果点P(x,y)在圆外,则以下的不等式必须为真:
现在,如果我们将(1)中的Rc替换为(2),那么在我们进行一些简单的计算后,将方程式平方:
(3.1)和(3.2)必须为真。
为简单起见,我们先写几点:
我们可以看到,对于给定的圆C(Xc,Yc),我们可以将(3)写成:
我们可以看到E(Xc)是关于Xc的线性函数,具有2个参数--A(x,y)和B(x,y)。这意味着基本上E(Xc)在欧几里德空间中表示具有2个参数的一族线。
现在这里是我不明白的部分。他们说,由于上段所述的属性,我们可以使用Envelope算法在O(1)摊销时间而不是O(N)时间内计算MIN()和MAX()。我不知道Envelope算法如何工作。
有关如何实施Envelope算法的任何提示?
提前致谢!
修改
问题不在于数学意义上的信封是什么 - 我已经知道了。问题是如何在更好的时间内确定包络O(n),显然它可以在摊销的O(1)中完成。
我有计算包络所需的函数族,并且我有一个所有可能参数的数组。如何以最佳方式解决最大化问题?
再次感谢!
答案 0 :(得分:1)
答案 1 :(得分:1)
我没有数学背景,但我会分三个步骤解决这个问题:
扔掉N中的大多数分数。这是棘手的部分。当从原点看时,每对点“遮蔽”一个“后面”的区域。该区域由两个光束分隔,这两个光束从点向外开始,指向原点,以及点之间的圆形交点。在极坐标中计算这个可能要简单得多。从随机对开始,然后一次看一个新点:如果它被遮挡,扔掉它;如果没有,找出它是否遮挡了你的集合中已经存在的任何点,然后重建包络的曲线集。重建包络曲线部分的测试应该花费几乎恒定的时间,因为阴影集不可能超过一定的小数。最坏的情况似乎是O(NlogN)。我无法想象任何解决方案都可以比O(N)更好,因为在任何情况下你都必须看每一点。
扔掉M中的大多数点。这很容易:如果M点远离原点而不是距离包络集最远点的距离的一半,则它可以被抛出。这需要O(M)
通过实际检查过滤M中的剩余点。它取决于N和M的分布,这需要多长时间,但我认为如果两个数字都很大且分布相似,那么几乎 O(1)。
总的来说,似乎可以在O(N log(N)+ M)中。但不保证;)
答案 2 :(得分:1)
答案 3 :(得分:1)
我认为你可以用Voronoi图做到这一点:
总体复杂度应为O(N log N + M log N)
答案 4 :(得分:0)
考虑一下计算的其他方面。
例如,你显然比较了很多距离。每个人都接到一个SQRT的电话。为什么不比较“距离的平方”。 SQRT是一项代价高昂的计算。
答案 5 :(得分:0)
永远不要拿sqrt。将所有距离保留为正方形。这样做,你也可以比较它们,但时间减少了2-3倍。