这是一个与语言无关的问题,更多的是面向算法设计。
想象一下,我们在3D空间中有两个点阵列(每个点都看起来像[(1, 0, 2), (2, 4, 32), ...]
)
第一个数组表示点的第一个状态,第二个数字表示稍后移动了一小部分(不一定每个都移动相同距离)的后一个状态。 注意:可能已删除了几个点,并在第二个状态中添加了一些新点。
问题:鉴于这两个数组,如何将每个移位点与其原始点匹配(达到合理的准确度),同时还要确定哪些点是新的并且不存在于第一个州?
想法:我认为可以应用某种k-means聚类,但我不确定如何处理某些点已被删除/添加的事实在州之间 - 所以我不认为这种方法会很好。
修改
不一定在数组中的任何特定位置添加点,并且不必为状态之间的持久点保持顺序。与独特点之间的距离相比,点在状态之间移动的距离应该相对较小 - 否则这个问题基本上是不可能的。
答案 0 :(得分:1)
这取决于一个假设:与第一组和第二组之间的唯一点之间的距离相比,移位距离非常小(基本上是模糊测量)。
首先,点集的一般结构不受平移,旋转或缩放的显着影响。这为您提供了很多选择。
获取每个维度的最小值/最大值(x,y,z等)。翻译和重新缩放两个点集。确切的缩放并不重要,但您可以使用它,使得所有点都是正的,并且在每个维度中都在0到100之间。这允许您更一致地比较点。虽然可能不是严格需要的,但可能会被忽略
然后你应该在点集A和点集B之间创建一个双向映射(双向图),它将是O(| A | + | B |),其中| A |和| B |是集的大小。
双向映射示例:
a_to_b[(1.001,2.001)] = [(1.005,1.995)]
b_to_a[(1.005,1.995)] = [(1.001,2.001)]
如果a_to_b
和b_to_a
相互映射,那么这是相同概率的相同点。
如果没有,那么您可能会看到类似的内容:
a_to_b[(1.001,2.007)] = [(1.005,1.995)]
b_to_a[(1.005,1.995)] = [(1.500, 2.004)]
a_to_b[(1.500, 2.004)] = [(1.495, 2.009)]
b_to_a[(1.495, 2.009)] = [(1.500, 2.004)]
由于不再有1-1映射,这意味着已添加或删除了某些内容。由于a中的值未映射回来,因此可能已删除。在相反的情况下,可能会增加。如果添加了,您将需要重新运行算法以尝试确定原始最近点是什么。
这可以通过查看不同的点并查看它是否是1-1映射的一部分(并因此被考虑)来验证。基本上,你想要考虑所有的1-1映射点(它们具有相同点的高概率),然后尝试整理不匹配的点
您可能希望获得两个点集的Delaunay三角剖分,以便能够更快地查找所有点的最近邻居,因为知道哪些点在空间上与给定点相邻。如果我回想起右边的Delaunay图中的边数是O(V),那么每个顶点的平均边是O(1)。一旦找到最近的点。但是,您可能需要对delaunary图进行一些调整以考虑添加/删除的边缘。
答案 1 :(得分:1)
将每个点与其最近邻居匹配,除非距离超过阈值。
如果你有多个可能的匹配,你需要设计一个好的解决策略。
将不匹配的点视为已删除或添加。
为了加快速度,请在数据上放置八叉树或网格文件,这样您只需要测试相邻的网格单元格,而不是将每个点与其他每个点进行比较。
答案 2 :(得分:0)
根据以下假设:
如果以上所有都是正确的,那么就没有能够提供合理水平可靠性的解决方案。
我可以添加许多可以证实我的断言的例子,但它看起来很直观,因此并不是真的需要。
修改强>:
在与Ted Hopp讨论后,我将基于两个INSERTED CRITICAL假设包含一种替代方法:
Lmin
,而任何移动的最大距离是<< LMin
我们称之为Mmax
。通过这两个额外的假设,你可以想到一个如下机制(类似JavaScript的代码 - 没有检查!):
for (i = 0 ; i < Points.Count ; i++) {
for (j = i + 1 ; j < Points.Count ; j++) {
if ((ABS(Array1[i].x - Array2[j].x) > Mmax ) ||
(ABS(Array1[i].y - Array2[j].y) > Mmax ) ||
(ABS(Array1[i].z - Array2[j].z) > Mmax ) ) {
// Distance between two points is for sure equal or bigger than max.
continue ; // Meaning, go to check next point.
}
// The check of the distance is split into two stages
// because, if the first if is true, the actual distance
// calculation is not needed (and hence time is saved).
if (Distance_Between_Points(Array1[i],Array2[j]) > Mmax) {
// Distance between two points is for sure bigger than max.
continue ; // Meaning, go to check next point.
}
// Points appear to be related!!!!!!
..........
}
}