更好的计算网格点数的算法
better algorithm for counting points in grids
假设我在[0,1]*[0,1]中有一个点p,并且[0,1]被划分为m(假设为200)个网格。我使用A[m][m]
来表示[以P为中心,长度为2h的小正方形]是否覆盖每个网格。因此对于点P, A[i][j]
为(递增)1或0。
假设我有n个这样的点(P1,…,Pn),我想计算A(对于每个点Pi,我重做上述过程,加1或不加1)。我如何有效地做到这一点(用c++),而不是编写3层for循环来检查每个网格和每个点(所以O(nm^2))?
我用c++尝试了简单的3 for循环。它比在r中使用一些矢量化操作(如vector<= number
用于比较n个数,A[bool vector, bool vector]
用于子集)需要更长的时间。
由于c++通常比R更快,有什么聪明的方法来实现这个过程吗?
#include <Rcpp.h>
#include <cmath>
using namespace Rcpp;
// [[Rcpp::export]]
double myfun(NumericVector u, NumericVector v)
{
double n = u.size();
double A[200][200] = {0};
double pos[200];
int i = 0, j = 0, k = 0;
for (i = 0; i < 200; i++)
{
pos[i] = (double)i / 201;
}
for (k = 0; k < n; k++)
{
for (i = 0; i < 200; i++)
{
for (j = 0; j < 200; j++)
{
if ( (fabs(u[k] - pos[i]) <= h) && (fabs(v[k] - pos[j]) <=h ) )
{
A[i][j]++;
}
}
}
}
double s = 0, avg = 0;
for (i = 0; i <200; i++)
{
for (j = 0; j < 200; j++)
{
s += A[i][j];
}
}
avg = s / (200 * 200);
return (avg);
}
这两个内部循环只决定网格中点的索引。但是你可以直接计算索引:
int i = (int)(u[k]*200);
int j = (int)(v[k]*200);
你可能还需要检查i
和j
没有达到索引200。这只发生在u[k] == 1.0
或v[k] == 1.0
。
double n = u.size();
double A[200][200] = {0};
for (int k = 0; k < n; k++)
{
int i = (int)(u[k]*200);
int j = (int)(v[k]*200);
if (i == 200)
i = 199;
if (j == 200)
j = 199;
A[i][j]++;
}
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 算法问题:查找从堆栈中弹出的所有序列
- 下面是排序算法O(n)吗
- KMP算法和LPS表构造的运行时间
- 用于查找网格中最短路径的算法
- 算法设计:用边界数字表示 2D 网格的最佳方式,以C++?
- 六边形网格上的算法
- 如何累积三维三角形网格的边?用c语言计算网格边的算法
- 网格和圆锥相交算法
- 从平面方程中生成点网格的算法
- 更好的计算网格点数的算法
- 在网格中寻找加号的算法
- 在网格上实现类dijkstra算法
- 使用 kinect 从点云生成三角形网格的算法