C 中的快速范围搜索实现
Fast rangesearch implementation in C++
我将与matlab中的rangesearch实现相同的功能。问题是数据确实很大(670万3D点(。我在C 中读取成对距离计算并改进代码,但还不够快。由于计算距离矩阵正在用于此数量数据的RAM消耗,因此不适用。我把代码放在这里。让我知道是否有一种方法可以更快。数据是在第一个维度上排序的,我想确保在每个点上,第一个邻居都是要点本身。
std::vector<std::vector<long int>> rangesearch(std::vector<std::vector<float>> &data, float radius) {
float distmat = 0;
float xdist = 0;
std::vector<std::vector<long int>> indices(data.size());
//This make sure that the first neighbour of each point is itself.
for (unsigned long int i = 0; i < data.size(); i++) {
indices[i].push_back(i);
}
// instead of computing sqrt() of distance, compute the 2nd power of radius once and compare it again and again which is faster
radius = std::pow(radius, 2);
for (unsigned long int i = 0; i < data.size(); i++) {
for (long int j = i + 1; j < data.size(); j++) {
xdist = std::pow(data[i][0] - data[j][0], 2);
distmat = xdist + std::pow(data[i][1] - data[j][1], 2) + std::pow(data[i][2] - data[j][2], 2);
if (distmat <= radius) {
indices[i].push_back(j);
indices[j].push_back(i);
}
//This is just to make the preprocessing faster. Data should be sorted based on X cordinates.
//Then if the distance for x cordinate is bigger than radius it means that it will be even bigger
// for the rest of the point so there is no need to check all of them and skip the rest!
if (xdist > radius)
break;
}
}
return indices;
}
您试图解决的问题看起来像最近的neighbor搜索或a n-n-body Simulation 。。
当前代码的最坏情况复杂性是O(n^2)
。使用n=6.7e6
,这意味着大约一亿迭代。当然,破坏条件,并行性和低级优化将有所帮助,但是结果代码仍然非常慢。因此,您需要找到更好的算法。
解决此类问题的常见方法是将所有元素放在BSP-Tree数据结构(例如Quadtree或Octree(中。这样的数据结构可帮助您在O(log(n))
时间内找到位置附近的最近元素。结果,此方法的总体复杂性是O(n log(n))
!
重要说明:
我以为半径很小。确实,如果radius
太大,则需要在整个树上迭代,从而产生二次复杂性。实际上,在这种情况下,书面输出的大小是二次的。因此,不幸的是,O(n^2)
将是最佳复杂性。
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- 尝试通过多个向量访问变量时,向量下标超出范围
- 有根的二进制搜索树.保留与其父级的链接
- 错误:未在此范围内声明'reverse'
- 变量未在此范围内声明 数组线性搜索
- C 中的快速范围搜索实现
- 如何在范围树中搜索
- 使用cctype库搜索函数,以查找某个范围内的数字字符数
- 是什么让这个二叉搜索更接近最大范围
- 二叉搜索以查找数字所在的范围
- 模板类C++符号范围搜索顺序不同
- 范围搜索的数据结构(重新访问)
- 使用std::equalrange来搜索某些范围内的向量
- 在字符串范围列表中搜索字符串
- 在搜索字符串时,Vector下标超出了范围
- 从范围的末尾开始搜索
- c ++二进制搜索排序的日期->我需要一个范围(CCA)
- 如何使用CGAL对三维点集进行范围搜索
- 在c++中搜索排序向量中的范围[x,y][使用lower_bound()和upper_bound()]
- 二进制搜索范围