你有把戏在圆圈上应用的技巧吗?

时间:2016-08-05 09:30:46

标签: c++ algorithm c++11 optimization a-star

我希望使用A *算法找到有限硬件(CPU:Vortex86,256 MB)上从A点到B点的良好路径。我有一个300x200的细胞网格,有固定的障碍物。避开障碍物的命中框是一个磁盘。

我正在寻找一种优化的方法,以检查我的命中箱是否与障碍物碰撞,因为它经常在A *中完成。

最明显的方法是检查磁盘的整个区域,如:

bool check(std::function<bool(const Coordinates &)> collide)
{
    const std::uint32_t RADIUS2 = radius * radius;
    Coordinates cell(-radius, -radius);

    for (; cell.x <= radius; cell.x++)
    {
        for (cell.y = -radius; cell.y <= radius; cell.y++)
        {
            if (cell.x * cell.x + cell.y * cell.y <= RADIUS2 && !collide(center + cell))
            {
                return false;
            }
        }
    }

    return true;
}

其中radius是磁盘的半径,center是磁盘中心的坐标。

更好的解决方案可能是只检查磁盘的周长。但是这两个解决方案都需要使用2个for循环,并且它在很大程度上不适合磁盘区域。

你有什么解决办法聪明地做到这一点吗?

1 个答案:

答案 0 :(得分:0)

在嵌套循环中,您正在调用Started. r1 1 r2 2 r1 1 r2 2 ... //When r2 is changed to 3 Started. r2 2 r1 1 r1 1 r1 1 r2 3 ... r2 2 r1 1 r2 3 。这是间接调用,具有非平凡的抽象惩罚。现在,现代 CPU将具有分支预测,这将在前几次调用后成功预测该分支。但是你的旧芯片会在那里遭受很多损失。

所以,你确实需要避免这种情况。幸运的是,第一条评论已经敲响了头部。通过计算障碍物周围的禁区,您可以有效地预先计算命中测试。

或者,假设障碍物不移动,您可以在每个细胞上缓存命中测试的结果。如果你有一个最初只需要一小部分的大网格,这就特别有效。