gpt4 book ai didi

c++ - A星算法

转载 作者:可可西里 更新时间:2023-11-01 16:40:05 29 4
gpt4 key购买 nike

我的 A-star 实现有问题。它确实找到了从我的点 A 到 B 的路径,但如果地形更“复杂”,那么我的 Find() 函数似乎不会结束。例如,它确实适用于此处的 20 x 20 阵列,但如果您在底部向最右侧的障碍物/墙添加一个正方形 ('#'),则它会失败。

我希望有人能指出我做的任何错误。这是我的代码:

#include <iostream>
#include <string>
#include <cmath>
#include <vector>
#include <utility>
#include <algorithm>
#include <queue>

using namespace std;

class CNode
{
public:

CNode() : xPos(0), yPos(0), travelCost(0) {}
CNode(int x, int y) : xPos(x), yPos(y), travelCost(0) {}
CNode(int x, int y, int cost) : xPos(x), yPos(y), travelCost(cost) {}

inline CNode& operator=(const CNode& target)
{
if (*this != target)
{
xPos = target.xPos;
yPos = target.yPos;
travelCost = target.travelCost;
}

return *this;
}

inline bool operator==(const CNode& target) const
{
return xPos == target.xPos && yPos == target.yPos;
}

inline bool operator!=(const CNode& target) const
{
return !(*this == target);
}

inline bool operator<(const CNode& target) const
{
return target.travelCost < travelCost;
}

int xPos, yPos, travelCost;
};

class CPath
{
public:

typedef vector<CNode> nodeList;

nodeList Find(const CNode& startNode, const CNode& endNode, int mapArray[][20])
{
nodeList finalPath, openList, closedList;

finalPath.push_back(startNode);
openList.push_back(startNode);
closedList.push_back(startNode);

while (!openList.empty())
{
// Check each node in the open list
for (size_t i = 0; i < openList.size(); ++i)
{
if (openList[i].xPos == endNode.xPos && openList[i].yPos == endNode.yPos)
return finalPath;

priority_queue<CNode> nodeQueue;

// Get surrounding nodes
for (int x = -1; x <= 1; ++x)
{
for (int y = -1; y <= 1; ++y)
{
const int current_x = openList[i].xPos + x;
const int current_y = openList[i].yPos + y;

bool alreadyCheckedNode = false;
for (size_t i = 0; i < closedList.size(); ++i)
{
if (current_x == closedList[i].xPos && current_y == closedList[i].yPos)
{
alreadyCheckedNode = true;
break;
}
}

if (alreadyCheckedNode)
continue;

// Ignore current coordinate and don't go out of array scope
if (current_x < 0 || current_x > 20 || current_y < 0 ||current_y > 20 || (openList[i].xPos == current_x && openList[i].yPos == current_y))
continue;

// Ignore walls
if (mapArray[current_x][current_y] == '#')
continue;

const int xNodeDifference = abs(current_x - (openList[i].xPos));
const int yNodeDifference = abs(current_y - (openList[i].yPos));

// Diagonal?
const int direction = xNodeDifference == 1 && yNodeDifference == 1 ? 14 : 10;

const int xDistance = abs(current_x - endNode.xPos);
const int yDistance = abs(current_y - endNode.yPos);
int heuristic = 10 * (xDistance + yDistance);

nodeQueue.push(CNode(current_x, current_y, heuristic));
}
}

if (!nodeQueue.empty())
{
// Add the nearest node
openList.push_back(nodeQueue.top());
finalPath.push_back(nodeQueue.top());

// Put into closed list
while (!nodeQueue.empty())
{
closedList.push_back(nodeQueue.top());
nodeQueue.pop();
}
}
}
}

return finalPath;
}
};

int mapArray[20][20] =
{
{ '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#' },
{ '#', 'A', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'B', '#' },
{ '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#' },

};

int main(int argc, char** argv)
{
CNode start, end;

for (int width = 0; width < 20; ++width)
{
for (int height = 0; height < 20; ++height)
{
if (mapArray[width][height] == 'A')
{
start.xPos = width;
start.yPos = height;
}
else if (mapArray[width][height] == 'B')
{
end.xPos = width;
end.yPos = height;
}
}
}

CPath pathFinder;
CPath::nodeList n = pathFinder.Find(start, end, mapArray);

for (int i = 0; i < n.size(); ++i)
if (mapArray[n[i].xPos][n[i].yPos] != 'A' && mapArray[n[i].xPos][n[i].yPos] != 'B')
mapArray[n[i].xPos][n[i].yPos] = '*';

for (int height = 0; height < 20; ++height)
{
for (int width = 0; width < 20; ++width)
{
if (width % 20 == 0)
cout << endl;

cout << (char)mapArray[height][width] << " ";
}
}

cin.get();

return 0;
}

最佳答案

当考虑一个节点的邻居时,你只把最上面的一个(最接近目的地的那个)放入openList以供进一步考虑;所有其余的直接进入closedList,在那里它们被认为是永远的alreadyCheckedNode。所以自然而然地,你的搜索器会朝 B 移动,直到它卡在一个角落里。

关于c++ - A星算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6990168/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com