C++ A*星型算法帮助c++;
我的打开和关闭列表有问题。如果我改变了B并移动它,它就不起作用,但是在地图的某些地方,如果我改变了B的位置,它就会再次起作用。如果有人能在我出错的地方帮助我,我将不胜感激。谢谢C++ A*星型算法帮助c++;,c++,algorithm,a-star,C++,Algorithm,A Star,我的打开和关闭列表有问题。如果我改变了B并移动它,它就不起作用,但是在地图的某些地方,如果我改变了B的位置,它就会再次起作用。如果有人能在我出错的地方帮助我,我将不胜感激。谢谢 #include <iostream> #include <string> #include <cmath> #include <vector> #include <utility> #include <algorithm> #include <
#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
类CNode
{
公众:
CNode():xPos(0)、yPos(0)、travelCost(0){}
CNode(intx,inty):xPos(x),yPos(y),travelCost(0){}
CNode(整数x,整数y,整数成本):XPO(x),YPO(y),旅行成本(成本){}
内联CNode和运算符=(常数CNode和目标)
{
如果(*此!=目标)
{
xPos=target.xPos;
yPos=target.yPos;
travelCost=target.travelCost;
}
归还*这个;
}
内联布尔运算符==(常量CNode和目标)常量
{
返回xPos==target.xPos&&yPos==target.yPos;
}
内联布尔运算符!=(常数CNode和目标)常数
{
返回!(*此==目标);
}
内联布尔运算符这似乎有很多问题:
你永远不会从openList弹出,这意味着每次你检查你已经查看过的节点,并将已经在openList或closedList中的节点推送到openList中。这会增加很多计算量
当您实际上只需要两个队列和列表时,您有许多队列和列表。您需要一个列表(或者更好的是,一个映射,这样就可以固定时间来检查节点是否已扩展)为了跟踪哪些节点已经扩展,您需要一个优先级队列来从中提取下一个节点。因此,您不必为openList使用嵌套的for循环,而只需使用while循环,然后每次都以最佳启发式值弹出节点(即,根据你的启发,你希望让你离目标最近的目标)
最终路径还有一些细节需要解决,但我认为只有两个而不是三个数据结构将使代码朝着正确的方向发展。准确地找出问题所在,或者至少是一个大致的方面。明确说明出了什么问题。没有人想通过查看代码来确定问题所在说一些不起作用的东西对你来说毫无意义。什么编译器没有警告就为你编译了这个?我已经说过OpenLIST和关闭列表有问题。我不知道哪里出了问题,所以我首先提出这个问题。我用C++。程序很好,但是如果你编辑地图代码,改变B的位置,用“#”创建一堵墙,然后路径不会回到B,但是当你去掉“#”并留出一段距离以获得一条新的路径时,它意味着要找到最短的路径,但它不是…好的,谢谢,你有什么办法我可以实现这一点,因为我不确定如何开始或从哪里开始。谢谢ll您已经在代码中使用了priorityQueue。如果您对使用映射感到困惑,那么总会有文档()。如果您想知道实际的实现,您已经设置了框架,您只需要稍微修改它,以便每次检查一个节点,获取其邻居,并将其推到PriorityQueue中。不幸的是,我没有时间!但是wikipedia文章有很好的指导原则。祝您好运!好的,谢谢您的帮助,最后一个你能给我指出我代码中的一点吗?你的意思是,对不起,我的英语不是很好,我觉得很难理解。我一直在写一行cin,它接受变量,然后用它们作为我的a*算法开始的位置。int xA,yA,xB,yB;switch(rand()%8){案例0:xA=0;yA=0;xB=n-1;yB=m-1;中断;案例1:xA=0;yA=m-1;xB=n-1;yB=0;中断;}