我的目标是更有效地实施提出in this question的算法。
考虑两组点(在N空间中.3空间用于RGB颜色空间的示例情况,而 1空间 2空间的解决方案仅在距离计算中不同)。如何在第一组中找到距离其最近邻居最远的第二组中的点?
在1空间的例子中,给定集A:{2,4,6,8}和B:{1,3,5},答案是 8,因为8距离5(距离B中最近的邻居)3个单位,而A的所有其他成员距离B中最近的邻居只有1个单位。编辑:1空间过于简化,因为排序与距离有关以某种方式,它不是更高的维度。
源问题中的解决方案涉及一组中每个点的强力比较(所有R,G,B,其中512> = R + G + B> = 256且R%4 = 0且G%4 = 0和B%4 = 0)到另一组中的每个点(colorTable)。为了这个问题,忽略第一个集合以编程方式进行详细说明,而不是像第二个集合那样作为存储列表进行迭代。
答案 0 :(得分:10)
首先,您需要在另一组中找到每个元素的最近邻居。
要有效地执行此操作,您需要nearest neighbor算法。就个人而言,我会实现一个kd-tree,因为我在算法类中已经完成了它并且它非常简单。另一个可行的替代方案是R-tree。
对最小集合中的每个元素执行一次此操作。 (从最小的一个元素添加一个元素,然后运行算法以找到它的最近邻居。)
从这里你应该能够获得每个元素的最近邻居列表。
在找到最近邻居对时,将它们保存在排序数据结构中,该结构具有快速添加方法和快速getMax方法,例如heap,按Euclidean distance排序。
然后,一旦完成,只需要求堆最大。
此运行时间分解如下:
N =较小组的尺寸
M =较大集合的大小
所以最后整个算法都是O(N * log M)。
如果您不关心每对的顺序,只需保留到目前为止的最大值,就可以节省一些时间和空间。
*免责声明:这一切都假设您不会使用极高数量的维度,并且您的元素主要是随机分布。
答案 1 :(得分:0)
在我看来,最明显的方法是在一组上构建树结构,以便您可以相对快速地搜索它。 kd-tree或类似的可能是适合的。
完成后,你走过另一组中的所有点,并使用树在第一组中找到最近的邻居,随时跟踪最大值。
构建树的nlog(n)和一次搜索的log(n)所以整个事情应该在nlog(n)中运行。
答案 2 :(得分:0)
为了提高效率,请考虑使用Pigeonhole算法 - 根据它们在n空间中的位置对参考集(您的colorTable)中的点进行分组。这使您可以有效地找到最近的邻居,而无需迭代所有点。
例如,如果你在2空间工作,将你的飞机划分为5 x 5网格,给出25个方格,有25组点。
在3个空间中,将立方体划分为5 x 5 x 5网格,给出125个立方体,每个立方体都有一组点。
然后,为了测试点n,找到包含n的方形/立方体/组以及到这些点的测试距离。如果点n更接近边缘而不是组中最近的邻居,则只需要测试相邻组中的点。
答案 3 :(得分:0)
对于集合B中的每个点,找到集合A中距其最近邻居的距离。
要找到距离每个最近邻居的距离,只要维度数量合理,点数不多,你就可以使用kd-tree,并且你会做很多查询 - 否则它会太贵了,不值得建树。
答案 4 :(得分:0)
也许我误解了这个问题,但是在一个数据集中反转所有坐标上的符号(即将一组坐标乘以-1)并不是最容易的,然后找到第一个最近的邻居(这将是最远的邻居)?您可以使用自己喜欢的knn算法,k = 1。
答案 5 :(得分:-1)
编辑:我的意思是nlog(n),其中n是两个集合大小的总和。
在1-Space集中我可以做这样的事情(伪代码)
使用这样的结构
Struct Item {
int value
int setid
}
(1)最大距离= 0
(2)将所有集合读入项目结构
(3)创建一个指向所有项目的指针数组
(4)通过结构
的Item-> value字段对指针数组进行排序
(5)从头到尾遍历数组,检查Item-> setid是否与前一个Item-> setid不同
if(SetIDs不同)
检查此距离是否大于最大距离,如果这样设置MaxDistance到此距离
返回最大距离。