C++ 在Z^3中寻找邻域的优化

C++ 在Z^3中寻找邻域的优化,c++,algorithm,C++,Algorithm,我有一个Z^3整数3元组中的点数组 如何快速确定每个点的邻居?其中,邻居是距离欧几里得度量正好一个单位距离的点 例如,假设数组为: {0,0,0},{0,0,1},{1,1,1} 然后{0,0,0}和{0,0,1}是邻居,{1,1,1}没有邻居 目前,我正在用std::vector对所有点进行字典排序,然后使用std::lower_bound搜索邻居6个二进制搜索。这比在我的测试数据中使用std::无序_映射要快得多 还有其他更快的方法吗?请注意,我不能使用常规网格,因为这些点可能相距很远。另请

我有一个Z^3整数3元组中的点数组

如何快速确定每个点的邻居?其中,邻居是距离欧几里得度量正好一个单位距离的点

例如,假设数组为:

{0,0,0},{0,0,1},{1,1,1}

然后{0,0,0}和{0,0,1}是邻居,{1,1,1}没有邻居

目前,我正在用std::vector对所有点进行字典排序,然后使用std::lower_bound搜索邻居6个二进制搜索。这比在我的测试数据中使用std::无序_映射要快得多

还有其他更快的方法吗?请注意,我不能使用常规网格,因为这些点可能相距很远。另请注意:由于下面有一些混淆,这是一个关于优化的问题,而不是正确性的问题。我上面建议的实现是微不足道的

对于测试数据集,假设一个半径为256的体素化球体

请注意,我不能使用常规网格,因为点可能比较远 分开

体育场茶壶问题可以通过多层网格或八叉树来解决。每个节点包含其父节点的1/8卷。因为所有东西都是整数,所以您可能可以通过字符而不是整数来实现这一点。他们只需要在树上爬一次,检查邻居的孩子,如果空了,就爬两次,检查邻居的父母。这应该是非常快的,因为对于最近的邻居,只有64个节点,而不是检查整个阵列有多少个?。我想只有64个节点就足够了,因为通过只检查每个点的x0+1、y0+1、z0+1,您不需要检查x0-1、y0-1、z0-1,因为它重复相同的内容。所以,包括它自己和邻居所有的父节点,它是8x8=64个节点,对于最近的邻居,即使是对角线,你们也可以对它们进行ommit,当然,也许你们可以对对角线进行ommit,只检查3x8=24个节点

当节点中没有点时,不要构建该节点。如果有,则只需使用char值0,1,2,3,4,5,6,7,从其父对象的角度显示其z索引


还可以为固定点提供缓存,可能是为了在需要重新计算场景时减少计算量。

这里有一个ON*logN解决方案:

按字典顺序对向量排序。 在向量上迭代以查找哪些项与向量中的前一项正好有一个单位的距离。i、 e

bool pointsAreNeighbors=absitem[0]-previitem[0]+absitem[1]-previitem[1]+absitem[2]-previitem[2]==1

如果上述表达式的计算结果为true,请将item及其前身previitem作为键/值对插入std::map或类似的基于键/值的数据结构,因为它们是结果集的一部分

再次按字典顺序对向量进行排序,但这次使用自定义排序函子,以便将每个项中的中间值视为最低顺序的子排序标准,而不是最后一个值

重复步骤2, 再次按字典顺序对向量进行排序,但这一次使用自定义排序函子,以使每个项中的第一个值被视为最低顺序的子排序标准,而不是最后一个值或中间值。 重复步骤2。 此时,结果集应该包含所有相邻对。
注意:最终结果集可能包含一些冗余对,例如,它可能同时包含A、B和B、A-取决于您的用例,您可能希望也可能不希望在以后过滤掉它们,或者,在步骤2中添加一点额外的逻辑,在将任何无序对插入结果集中之前交换其密钥和值。

字典顺序不应该起作用。。。idk,我没有想太多,但是我第一眼看到字典顺序漏掉了很多例子。@dyz-所以6,1,0和3,3,2是邻居?好的,我发现了一个字典顺序和下限失败的简单例子:{2 2 2}{2 2 3}{2 2 4}{3 2 2}。关于{2}:在他和一个邻居{3 2}@Taylor之间有一个非邻居{2 2}@Taylor,请按照bolov所说的回答。他按字典顺序取了4个点{2 2}{2 2 3}{2 2 4}{3 2},证明了存在被非邻居{2 2 4}分隔的邻居{2 2}和{3 2}。这证明了下限不起作用,因为排序不会将邻域分组在一起。如果上面的逻辑有错误,请解决这个问题,而不是说这不是我正在做的。我敢肯定,我们大多数人都有相同的思维过程,这是一个算法问题或C++问题。如果你知道算法,它描述了一个复杂的过程,但是你不知道如何在C++中实现它的一部分,然后显示你已经实现的,并确切地描述缺少的内容。如果你甚至不知道算法应该是什么——这听起来是什么样的——那么这与C++无关。首先,你需要弄清楚算法是什么。否则,请尝试查看此库函数是否有效,或者该库是否有趣 行动会起作用,是浪费时间。