【问题标题】:Optimization of three dimensional problem where I loop through all items and consider distances to all other items优化三维问题,我循环遍历所有项目并考虑到所有其他项目的距离
【发布时间】:2018-10-31 03:44:49
【问题描述】:

我必须考虑一个三维空间,其中元素是均匀分布的。每个元素由三个坐标 x、y 和 z 描述。我必须以这种方式计算它们之间的距离:

float distance = 0;
for(int ix = 0; ix<n; ix++) {
    for(int iy = 0; iy<n; iy++) {
        for(int iz = 0; iz<n; iz++) {

            for(int jx = 0; jx<n; jx++) {
                for(int jy = 0; jy<n; jy++) {
                    for(int jz = 0; jz<n; jz++) {
                        distance = distance + calcDistance(ix, iy, iz, jx, jy, jz) / 2
                    }
                }
            }

        }
    }
}

对于超过 100 000 个项目的多维数据集,这需要相当长的时间。我除以两个,因为每个距离都被计算两次,但如果我可以省略第二次计算,我可能会加倍速度。

在一维中,这很容易。一个从 0 到 n 的循环,另一个从 i 到 n 的循环,我只考虑每个距离一次。但我不能在这里做同样的事情。有没有办法优化这个?

【问题讨论】:

  • 很确定有一个公式

标签: loops optimization mathematical-optimization


【解决方案1】:

作弊。经常作弊。

假设“左、上、前”点是point[0][0][0],这是我们唯一关心的点。其右侧的点距离为 1 距离,右侧的下一个点距离为 2 距离,......同样的“简单加法”也适用于其他 2 轴。您只需要计算对角线的距离(从point[0][0][0] 到不在完美右/下/后方向的任何其他点)。

得到point[0][0][0] 和所有其他点之间的所有距离后,您可以反转它们以找到所有其他点到point[0][0][0] 的所有距离。

现在...从point[x1][y1][z1]point[x2][y2][z2] 的距离将与从point[x1][y1][z1]point[x2][y2][z2] 的距离完全相同;这两者都将与point[0][0][0]point[x2-x1][y2-y2][z2-z1] 的距离完全相同。这意味着您可以使用(从上方)已经拥有的“与point[0][0][0] 的距离”作为查找表来查找所有其他点之间的所有其他距离;无需对其中任何一个进行(假设更昂贵)sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1) ) ); 计算。

当然,如果您使用(从上方)已经拥有的“与point[0][0][0] 的距离”作为查找表,那么存储这些距离可能根本没有意义。您可以在需要时使用查找表中的值(无需将其存储在其他位置)。

换句话说;我想要这样的函数(在 C 中):

static double getDistance( int x1, int y1, int z1, int x2, int y2, int z2) {
    int dx = abs(x1-x2);
    int dy = abs(y1-y2);
    int dz = abs(z1-z2);
    return distanceTable[dx][dy][dz];
}

在这种情况下,您必须预先计算距离表(即上面的“从point[0][0][0] 到每个其他点的距离”)。

但是,如果你想偷懒,做这样的事情可能会更有趣:

static double getDistance( int x1, int y1, int z1, int x2, int y2, int z2) {
    int dx = abs(x1-x2);
    int dy = abs(y1-y2);
    int dz = abs(z1-z2);
    if(dx+dy+dz == 0) return 0.0;

    double distance = distanceTable[dx][dy][dz];
    if(distance == 0.0) {
        distance = sqrt(dx*dx + dy*dy + dz*dz);
        distanceTable[dx][dy][dz] = distance;
    }
    return distance;
}

【讨论】:

    猜你喜欢
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多