优化在 Z^3 中查找邻居
optimizing finding neighbors in Z^3
我在 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::unordered_map
要快得多。
有没有另一种方法可以更快?(请注意,我不能使用常规网格,因为点可能相距很远。另请注意:由于下面有一些混淆,这是一个关于优化的问题,而不是正确性。我上面建议的实现是微不足道的。
对于测试数据集,假设有一个半径为 256 的体素化球体。
请注意,我不能使用常规网格,因为点可能很远 分开
体育场中的茶壶问题可以通过多级网格或一些八叉树来解决。每个节点包含其父节点的 1/8 卷。由于一切都是整数,因此您可以通过字符而不是整数来执行此操作。他们只需要在树上上走一次,检查邻居的孩子,如果空了,上去两次,检查邻居的父母。这应该比检查整个阵列(多少个?(快得多(最近邻居可能只有 64 个节点(。我想只有 64 个节点就足够了,因为通过为每个点只检查 x0+1,y0+1,z0+1,你不需要检查 x0-1、y0-1、z0-1,因为它重复了相同的东西。因此,包括自身和邻居(所有父节点(是 8x8=64 个最近的邻居节点(即使是对角线,您当然可以省略它们(也许您可以省略对角线并仅检查 3x8=24 个节点。
当节点中没有点时,不要构建该节点。如果有,则只需有一个字符值 0,1,2,3,4,5,6,7,从其父级的角度显示其 (z 索引(。
还可以为静止点提供缓存,这可能是为了在需要重新计算场景时减少计算次数。
这是一个 O(N*log(N(( 解决方案:
- 按字典顺序对向量进行排序。
-
遍历向量以查找哪些项与向量中的前置项正好相距一个单位。 即
bool pointsAreNeighbors = (abs(item[0]-prevItem[0])+abs(item[1]-prevItem[1])+abs(item[2]-prevItem[2])==1);
如果上述表达式计算为 true,请将
item
(及其前身prevItem
(作为键/值对插入到std::map
(或类似的基于键/值的数据结构(中,因为它们是结果集的一部分。 -
再次按字典顺序对向量进行排序,但这次使用自定义排序函子,以便将每个项目中的中间值视为最低阶子排序条件(而不是最后一个值(。
- 重复步骤 2,
- 再次按字典顺序对向量进行排序,但这次使用自定义排序函子,以便将每个项目中的第一个值视为最低阶子排序条件(而不是最后一个值或中间值(。
- 重复步骤 2。
- 此时,结果集应包含所有相邻对。
注意:最终的结果集可能包含一些冗余对(例如,它可能同时包含(A,B(和(B,A(((——根据您的用例,您可能希望也可能不希望在之后过滤掉这些对,或者向步骤(2(添加一些额外的逻辑,以便在将任何"乱序对"插入结果集之前交换其键和值。
- 正在查找文档以获得PS4平台的C++中的设备信息
- 在C++中查找文件
- 模板元程序查找相似的连续类型名称
- 在UNIX系统中使用DIR查找文件的字节大小
- 查找最接近的大于当前数字的数字的索引
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 查找后更改类变量
- 使用正则表达式regex_search在字符串中查找字符串
- 使用gcc从静态链接的文件中查找可选符号
- 在C++中查找范围的长度
- 算法问题:查找从堆栈中弹出的所有序列
- 在Windows中查找扬声器输出的当前音量级别
- 如何在C++中使用X509证书模在令牌中查找私钥
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 优化在 Z^3 中查找邻居
- 在 3D 点云、GPU 中查找最近的邻居
- C++-使用opencv-frann查找最近的邻居
- 在 KD 树中查找最近的邻居
- 查找最近的邻居-OpenCV