C++ A*寻路缓慢

C++ A*寻路缓慢,c++,performance,algorithm,maze,C++,Performance,Algorithm,Maze,我目前正在研究a*搜索算法。该算法将只是解决文本文件迷宫。我知道A*算法应该能很快找到终点。在一个没有围墙的20x20迷宫中,我的迷宫似乎需要6秒钟才能找到路径。它确实找到了正确的路径,这需要永远的努力 如果我知道代码的哪一部分是问题所在,我会发布它,但我真的不知道哪里出了问题。这是我使用的算法 while(!openList.empty()) { visitedList.push_back(openList[index]); openList.erase(openList

我目前正在研究a*搜索算法。该算法将只是解决文本文件迷宫。我知道A*算法应该能很快找到终点。在一个没有围墙的20x20迷宫中,我的迷宫似乎需要6秒钟才能找到路径。它确实找到了正确的路径,这需要永远的努力

如果我知道代码的哪一部分是问题所在,我会发布它,但我真的不知道哪里出了问题。这是我使用的算法

 while(!openList.empty()) {  
    visitedList.push_back(openList[index]);
    openList.erase(openList.begin() + index);

    if(currentCell->x_coor == goalCell->x_coor && currentCell->y_coor == goalCell->y_coor)          
    }
        FindBestPath(currentCell);
        break;
    }

    if(map[currentCell->x_coor+1][currentCell->y_coor] != wall)
    {
    openList.push_back(new SearchCell(currentCell->x_coor+1,currentCell->y_coor,currentCell));
    }
    if(map[currentCell->x_coor-1][currentCell->y_coor] != wall) 
    {
        openList.push_back(new SearchCell(currentCell->x_coor-1,currentCell->y_coor,currentCell));
    }
    if(map[currentCell->x_coor][currentCell->y_coor+1] != wall) 
    {
        openList.push_back(new SearchCell(currentCell->x_coor,currentCell->y_coor+1,currentCell));
    }
    if(map[currentCell->x_coor][currentCell->y_coor-1] != wall) 
    {
        openList.push_back(new SearchCell(currentCell->x_coor,currentCell->y_coor-1,currentCell));
    }

    for(int i=0;i<openList.size();i++) {
        openList[i]->G = openList[i]->parent->G + 1;
        openList[i]->H = openList[i]->ManHattenDistance(goalCell);
    }

    float bestF = 999999;
    index = -1;

    for(int i=0;i<openList.size();i++) {
        if(openList[i]->GetF() < bestF) {
            for(int n=0;n<visitedList.size();n++) {
                if(CheckVisited(openList[i])) {
                    bestF = openList[i]->GetF();
                    index = i;
                }
            }
        }
    }
    if(index >= 0) {
        currentCell = openList[index];
    }
}
while(!openList.empty()){
visitedList.push_back(openList[index]);
擦除(openList.begin()+索引);
如果(currentCell->x_coor==goalCell->x_coor&¤tCell->y_coor==goalCell->y_coor)
}
FindBestPath(currentCell);
打破
}
如果(映射[currentCell->x_coor+1][currentCell->y_coor]!=墙)
{
openList.push_back(新的搜索单元格(currentCell->x_-coor+1,currentCell->y_-coor,currentCell));
}
如果(映射[currentCell->x_coor-1][currentCell->y_coor]!=墙)
{
openList.push_back(新的搜索单元(currentCell->x_coor-1,currentCell->y_coor,currentCell));
}
如果(映射[currentCell->x_coor][currentCell->y_coor+1]!=wall)
{
openList.push_back(新的搜索单元(currentCell->x_-coor,currentCell->y_-coor+1,currentCell));
}
如果(映射[currentCell->x_coor][currentCell->y_coor-1]!=wall)
{
openList.push_back(新的搜索单元(currentCell->x_-coor,currentCell->y_-coor-1,currentCell));
}
对于(inti=0;iG=openList[i]->parent->G+1;
openList[i]->H=openList[i]->ManhattinDistance(目标单元格);
}
浮动最佳频率=999999;
指数=-1;
对于(int i=0;iGetF()=0){
currentCell=开放列表[索引];
}
}
我知道这段代码很混乱,不是最有效的方法,但我认为它应该比现在更快。任何帮助都将不胜感激


谢谢。

你的20x20迷宫没有墙壁,因此有很多很多相同长度的路线。事实上,我估计有数万亿条相同的路线。如果你考虑到这一点,情况似乎并不那么糟糕


当然,由于您的启发式看起来很完美,您应该从排除经过启发式预测的路线中获得很大的好处,这些路线与目前已知的最佳路线一样长。(如果您的启发式是正确的,这是安全的,即决不高估剩余距离).

你的20x20迷宫没有墙壁,因此有很多很多相同长度的路线。事实上,我估计有数万亿条相同的路线。考虑到这一点,情况似乎并不那么糟糕


当然,由于您的启发式看起来很完美,您应该从排除启发式预测的路线中获益匪浅,这些路线与目前已知的最佳路线一样长。(如果您的启发式是正确的,这是安全的,即永远不会高估剩余距离)。

您不是一直在回溯吗

当当前最佳解决方案比以前访问过的另一条路径更差时,A*算法会回溯。在您的情况下,因为没有墙,所以所有路径都是好的,永远不会消亡(正如MSalters正确指出的,有几个路径).当你迈出一步时,你的路线会比其他所有短一步的路线更糟


如果这是真的,那么这就可以解释你的算法所花费的时间。

你不是一直在回溯吗

当当前最佳解决方案比以前访问过的另一条路径更差时,A*算法会回溯。在您的情况下,因为没有墙,所以所有路径都是好的,永远不会消亡(正如MSalters正确指出的,有几个路径).当你迈出一步时,你的路线会比其他所有短一步的路线更糟


如果这是真的,这可能会说明您的算法所花费的时间。

openList.erase
是O(n),以
for开头的for循环(inti=0;i
openList.erase
是O(n),而以
for开头的for循环(inti=0;i这里有一个很大的提示

如果你找到两条通往同一个牢房的路,你总是可以扔掉较长的一条。如果有平局,你可以扔掉第二条

如果在没有其他优化的情况下实现了这一点,那么搜索速度将达到可以接受的程度

其次,如果到当前单元格的长度加上启发式超过到当前单元格的长度加上任何其他节点的启发式,A*算法应该只麻烦回溯。如果您实现了这一点,那么它应该直接找到路径并停止。为了方便起见,您需要将路径存储在优先级队列中(通常使用堆实现),而不是向量。

这里有一个重要提示

如果你找到两条通往同一个牢房的路,你总是可以扔掉较长的一条。如果有平局,你可以扔掉第二条

如果在没有其他优化的情况下实现了这一点,那么搜索速度将达到可以接受的程度


其次,如果到当前单元格的长度加上启发式超过到当前单元格的长度加上任何其他节点的启发式,A*算法应该只麻烦回溯。如果您实现了这一点,那么它应该直接找到路径并停止。为了方便起见,您需要将路径存储在优先级队列中(通常使用堆实现),而不是向量。

我会使用类似ctime()的东西然后开始计时你正在做的不同操作,以找出大部分计算时间花在哪里。有时很难判断算法花在哪里,我发现这是一种在其他所有操作都失败时找到它的好方法。顺便说一句,我不想吹毛求疵,但距离的正确名称是曼哈顿(喜欢这个城市,因为它