【发布时间】:2014-07-30 16:45:35
【问题描述】:
语言/编译器:C++ (Visual Studio 2013) 经验:~2 个月
我在 3D 空间中的矩形网格中工作(大小:xdim by ydim by zdim)其中,“xgrid、ygrid 和 zgrid”分别是 x、y 和 z 坐标的 3D 数组。现在,我有兴趣找到以点“(vi,vj,vk)”为中心的半径为“r”的球体内的所有点。我想将这些点的索引位置存储在向量“xidx,yidx,zidx”中。对于单个点,该算法可以工作并且足够快,但是当我希望迭代 3D 空间内的许多点时,我会遇到很长的运行时间。
有没有人对我如何改进这个算法在 C++ 中的实现有任何建议?运行一些分析软件后,我在网上找到了(非常困,Luke stackwalker),似乎“std::vector::size”和“std::vector::operator[]”成员函数让我的代码陷入困境。非常感谢任何帮助。
注意:由于我不知道球体内有多少体素,因此我将向量 xidx,yidx,zidx 的长度设置为大于必要的长度,然后在函数末尾擦除所有多余的元素。
void find_nv(int vi, int vj, int vk, vector<double> &xidx, vector<double> &yidx, vector<double> &zidx, double*** &xgrid, double*** &ygrid, double*** &zgrid, int r, double xdim,double ydim,double zdim, double pdim)
{
double xcor, ycor, zcor,xval,yval,zval;
vector<double>xyz(3);
xyz[0] = xgrid[vi][vj][vk];
xyz[1] = ygrid[vi][vj][vk];
xyz[2] = zgrid[vi][vj][vk];
int counter = 0;
// Confine loop to be within boundaries of sphere
int istart = vi - r;
int iend = vi + r;
int jstart = vj - r;
int jend = vj + r;
int kstart = vk - r;
int kend = vk + r;
if (istart < 0) {
istart = 0;
}
if (iend > xdim-1) {
iend = xdim-1;
}
if (jstart < 0) {
jstart = 0;
}
if (jend > ydim - 1) {
jend = ydim-1;
}
if (kstart < 0) {
kstart = 0;
}
if (kend > zdim - 1)
kend = zdim - 1;
//-----------------------------------------------------------
// Begin iterating through all points
//-----------------------------------------------------------
for (int k = 0; k < kend+1; ++k)
{
for (int j = 0; j < jend+1; ++j)
{
for (int i = 0; i < iend+1; ++i)
{
if (i == vi && j == vj && k == vk)
continue;
else
{
xcor = pow((xgrid[i][j][k] - xyz[0]), 2);
ycor = pow((ygrid[i][j][k] - xyz[1]), 2);
zcor = pow((zgrid[i][j][k] - xyz[2]), 2);
double rsqr = pow(r, 2);
double sphere = xcor + ycor + zcor;
if (sphere <= rsqr)
{
xidx[counter]=i;
yidx[counter]=j;
zidx[counter] = k;
counter = counter + 1;
}
else
{
}
//cout << "counter = " << counter - 1;
}
}
}
}
// erase all appending zeros that are not voxels within sphere
xidx.erase(xidx.begin() + (counter), xidx.end());
yidx.erase(yidx.begin() + (counter), yidx.end());
zidx.erase(zidx.begin() + (counter), zidx.end());
return 0;
【问题讨论】:
-
vector::size未出现在发布的代码中。你确定这是程序的慢部分吗?此外,您永远不应该在优化构建的堆栈跟踪中看到size和operator[],因为这些简单的函数总是被内联的。请务必将-O3传递给编译器,或者从 IDE 中选择“发布”版本而不是“调试”版本。 -
@Potatoswatter 非常感谢您的及时回复。我使用了“发布”版本,这大大提高了我的代码速度。
-
@Potatoswatter,
size可能被用作[]运算符的一部分以检测边界问题。 -
要添加的相关信息是您的编译器、编译器标志和操作系统。还有,你给
find_nv打了多少电话 -
在循环之前预计算
rsqr,而不是为每个点重新计算。
标签: c++ algorithm vector multidimensional-array