c++在通过A*搜索找到路径后,打印路径会持续打印相同的Nodes信息
c++ after finding the path from an A* search, printing the path continually prints the same Nodes information
我已经设法使用c++生成了一个A*搜索(尽管它可能会更有效率),它确实从开始[x][y]到目标[x][y]并终止。
我遇到的问题是,当我想打印这条路径的坐标是遵循我尝试通过以下指针到每个节点的父,并继续做的事情,直到指针== NULL。
问题是,当我执行我的打印方法,它不断打印最终状态的坐标,而不是跟随指针到它的父,直到没有父(回到根节点)
Node.h
class Node{
private:
int xCoord;
int yCoord;
int value;
double fCost;
double gCost;
double hCost;
Node* parent;
public:
Node();
Node(int x, int y, int value, int cost, Node* parent);
void setParent(Node* parent);
int getX();
int getY();
int getValue();
double getHCost();
double getFCost();
double getGCost();
Node* getParent();
void setHCost(double hCost);
};
struct NodeComparator {
bool operator()(Node& first, Node& second) {
return (first.getFCost() < second.getFCost());
}
};
Node.cpp
Node::Node(){
this->xCoord = 0;
this->yCoord = 0;
this->value = 0;
this->parent = NULL;
this->fCost = 0;
this->gCost = 0;
this->hCost = 0.0;
}
Node::Node(int _x, int _y, int _value, int cost, Node* parent){
this->xCoord = _x;
this->yCoord = _y;
this->value = _value;
this->gCost = cost;
this->parent = parent;
this->hCost = 0.0;
this->fCost = 0;
}
void Node::setParent(Node* par){
this->parent = par;
}
int Node::getX(){
return xCoord;
}
int Node::getY(){
return yCoord;
}
int Node::getValue(){
return value;
}
double Node::getGCost(){
return gCost;
}
double Node::getFCost(){
return gCost + hCost;
}
double Node::getHCost(){
return hCost;
}
Node* Node::getParent(){
return parent;
}
void Node::setHCost(double cost){
this->hCost = cost;
}
实际进行搜索的main.cpp文件:
int main(){
int map[20][20] = {{0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,2},
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0},
{0,0,3,0,0,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0},
{0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0}};
using namespace std;
list<Node> openList;
vector<Node> closedList;
Node end;
Node start = initiateStart(map);
openList.push_front(start);
cout <<"Start index: x " << start.getX() << " y " <<start.getY() << endl;
while (!openList.empty()) {
Node best = openList.front();
openList.pop_front();
if(!checkInClosedList(closedList, best.getX(), best.getY())){
calcManhattanDistance(best, map);
if(best.getValue() == 3){
end = best;
cout <<"end index: x " << end.getX() << " y " <<end.getY() << endl;
checkPath(&end, map);
exit(1);
}
if(map[best.getX()][best.getY()-1] != 1 && best.getY() - 1 > -1){
if(placeInOpen(openList,best.getX(), best.getY() - 1)){
openList.push_front(generateLeftChild(best, map));
}
}
//to the right
if(map[best.getX()][best.getY()+1] != 1 && best.getY() + 1 < 20){
if(placeInOpen(openList,best.getX(), best.getY() + 1)){
openList.push_front(generateRightChild(best, map));
}
}
//above
if(map[best.getX()-1][best.getY()] != 1 && best.getX() - 1 > -1){
if(placeInOpen(openList,best.getX()-1, best.getY())){
openList.push_front(generateAboveChild(best, map));
}
}
//below
if(map[best.getX()+1][best.getY()] != 1 && best.getX() + 1 < 20){
if(placeInOpen(openList,best.getX()+1, best.getY())){
openList.push_front(generateBelowChild(best, map));
}
}
closedList.push_back(best);
}
openList.sort(NodeComparator());
}
return 0;
}
Node initiateStart(int m[20][20]){
Node start;
for(int i = 0; i < 20; i++){
for(int j = 0; j < 20; j++){
if(m[i][j] == 2){
start = Node(i, j, m[i][j], 0, NULL);
}
}
}
return start;
}
Node generateLeftChild(Node parent, int m[20][20]){
Node child;
child = Node(parent.getX(), parent.getY() - 1, m[parent.getX()][parent.getY() - 1],
parent.getGCost() + 1, &parent);
calcManhattanDistance(child, m);
return child;
}
Node generateRightChild(Node parent, int m[20][20]){
Node child;
child = Node(parent.getX() , parent.getY() + 1, m[parent.getX()][parent.getY() + 1],parent.getGCost() + 1, &parent);
calcManhattanDistance(child, m);
return child;
}
Node generateAboveChild(Node parent, int m[20][20]){
Node child;
child = Node(parent.getX() - 1, parent.getY(), m[parent.getX() - 1][parent.getY()],
parent.getGCost() + 1, &parent);
std::cout << "parent for above child X: " << child.getParent()->getX() <<" Y: "
<< child.getParent()->getY() << std::endl;
calcManhattanDistance(child, m);
return child;
}
Node generateBelowChild(Node parent, int m[20][20]){
Node child;
child = Node(parent.getX() + 1, parent.getY(), m[parent.getX() + 1][parent.getY()],
parent.getGCost() + 1, &parent);
calcManhattanDistance(child, m);
return child;
}
void calcManhattanDistance(Node node, int m[20][20]){
int tempX;
int tempY;
double manhattanDistance;
int differenceX;
int differenceY;
//std::cout << "node x: " << node->getX() << " node y: " << node->getY() << std::endl;
for(int i = 0; i < 20; i++){
for(int j = 0; j < 20; j++){
if(m[i][j] == 3){
tempX = i;
tempY = j;
}
}
}
//sum of term difference, none of these can be negative hense the std::abs
differenceX = tempX - node.getX();
differenceY = tempY - node.getY();
manhattanDistance = std::abs(differenceX) + std::abs(differenceY);
//std::cout << "Manhattan distance: " << manhattanDistance << std::endl;
node.setHCost(manhattanDistance);
}
bool checkInClosedList(std::vector<Node>& v,int x, int y){
for (std::vector<Node>::iterator iter = v.begin(); iter != v.end(); ++iter) {
if(iter->getX() == x && iter->getY() == y){
return true;
}
}
return false;
}
bool placeInOpen(std::list<Node>& v,int x, int y){
for (std::list<Node>::iterator iter = v.begin(); iter != v.end(); ++iter) {
if(iter->getX() == x && iter->getY() == y){
return false;
}
}
return true;
}
void checkPath(Node *end, int m[20][20]){
int tempX, tempY;
Node *temp = end;
while(temp != NULL){
tempX = temp->getX();
tempY = temp->getY();
std:: cout << tempX << " " << tempY << std::endl;
temp = temp->getParent();
}
printMap(m);
}
void printMap(int m[20][20]){
std::cout << "printy mcprint" << std::endl;
for(int i = 0; i< 20; i++){
for(int j = 0; j< 20; j++){
std::cout << m[i][j];
}
std::cout<<std::endl;
}
}
对不起的大代码转储,但我认为你会想看到一切,只是在万一我设置了一个错误的父母的地方!
我添加了一条print语句来测试我如何添加父节点,您可以在generateAboveChild
函数中看到这一点,程序产生如下输出:
Start index: x 0 y 19
parent for above child X: 1 Y: 19
parent for above child X: 2 Y: 19
parent for above child X: 3 Y: 19
parent for above child X: 2 Y: 18
parent for above child X: 1 Y: 17
parent for above child X: 4 Y: 19
parent for above child X: 5 Y: 19
parent for above child X: 4 Y: 18
parent for above child X: 3 Y: 17
parent for above child X: 2 Y: 16
parent for above child X: 1 Y: 15
parent for above child X: 1 Y: 14
parent for above child X: 6 Y: 19
parent for above child X: 7 Y: 19
parent for above child X: 6 Y: 18
parent for above child X: 5 Y: 17
parent for above child X: 4 Y: 16
parent for above child X: 3 Y: 15
parent for above child X: 2 Y: 14
parent for above child X: 3 Y: 14
parent for above child X: 8 Y: 19
parent for above child X: 9 Y: 19
parent for above child X: 8 Y: 18
parent for above child X: 7 Y: 17
parent for above child X: 5 Y: 15
parent for above child X: 4 Y: 14
parent for above child X: 4 Y: 13
parent for above child X: 6 Y: 15
parent for above child X: 8 Y: 17
parent for above child X: 10 Y: 19
parent for above child X: 11 Y: 19
parent for above child X: 10 Y: 18
parent for above child X: 9 Y: 17
parent for above child X: 7 Y: 15
parent for above child X: 6 Y: 14
parent for above child X: 5 Y: 13
parent for above child X: 4 Y: 11
parent for above child X: 8 Y: 15
parent for above child X: 10 Y: 17
parent for above child X: 12 Y: 19
parent for above child X: 13 Y: 19
parent for above child X: 12 Y: 18
parent for above child X: 11 Y: 17
parent for above child X: 9 Y: 15
parent for above child X: 8 Y: 14
parent for above child X: 7 Y: 13
parent for above child X: 6 Y: 12
parent for above child X: 5 Y: 11
parent for above child X: 4 Y: 9
parent for above child X: 3 Y: 10
parent for above child X: 14 Y: 19
parent for above child X: 15 Y: 19
parent for above child X: 14 Y: 18
parent for above child X: 13 Y: 17
parent for above child X: 12 Y: 16
parent for above child X: 10 Y: 14
parent for above child X: 9 Y: 13
parent for above child X: 8 Y: 12
parent for above child X: 7 Y: 11
parent for above child X: 6 Y: 10
parent for above child X: 2 Y: 10
parent for above child X: 5 Y: 9
parent for above child X: 3 Y: 8
parent for above child X: 1 Y: 10
parent for above child X: 7 Y: 10
parent for above child X: 16 Y: 19
parent for above child X: 17 Y: 19
parent for above child X: 16 Y: 18
parent for above child X: 15 Y: 17
parent for above child X: 14 Y: 16
parent for above child X: 13 Y: 15
parent for above child X: 12 Y: 14
parent for above child X: 11 Y: 13
parent for above child X: 10 Y: 12
parent for above child X: 8 Y: 10
parent for above child X: 2 Y: 7
parent for above child X: 1 Y: 8
parent for above child X: 18 Y: 19
parent for above child X: 19 Y: 19
parent for above child X: 18 Y: 18
parent for above child X: 17 Y: 17
parent for above child X: 16 Y: 16
parent for above child X: 15 Y: 15
parent for above child X: 14 Y: 14
parent for above child X: 13 Y: 13
parent for above child X: 12 Y: 12
parent for above child X: 11 Y: 11
parent for above child X: 2 Y: 5
parent for above child X: 1 Y: 6
parent for above child X: 15 Y: 14
parent for above child X: 19 Y: 17
parent for above child X: 18 Y: 16
parent for above child X: 17 Y: 15
parent for above child X: 16 Y: 14
parent for above child X: 14 Y: 12
parent for above child X: 13 Y: 11
parent for above child X: 12 Y: 10
parent for above child X: 3 Y: 4
parent for above child X: 2 Y: 3
parent for above child X: 1 Y: 4
parent for above child X: 13 Y: 10
parent for above child X: 15 Y: 12
parent for above child X: 17 Y: 14
parent for above child X: 19 Y: 15
parent for above child X: 18 Y: 14
parent for above child X: 16 Y: 12
parent for above child X: 15 Y: 11
parent for above child X: 14 Y: 10
parent for above child X: 4 Y: 4
parent for above child X: 5 Y: 4
parent for above child X: 4 Y: 3
parent for above child X: 3 Y: 2
parent for above child X: 2 Y: 1
parent for above child X: 1 Y: 2
parent for above child X: 15 Y: 10
parent for above child X: 17 Y: 12
parent for above child X: 19 Y: 14
parent for above child X: 18 Y: 12
parent for above child X: 17 Y: 11
parent for above child X: 16 Y: 10
parent for above child X: 6 Y: 4
parent for above child X: 7 Y: 4
parent for above child X: 6 Y: 3
parent for above child X: 5 Y: 2
parent for above child X: 4 Y: 1
parent for above child X: 3 Y: 0
parent for above child X: 1 Y: 0
parent for above child X: 19 Y: 12
parent for above child X: 19 Y: 11
parent for above child X: 18 Y: 10
parent for above child X: 17 Y: 9
parent for above child X: 4 Y: 0
parent for above child X: 8 Y: 4
parent for above child X: 9 Y: 4
parent for above child X: 8 Y: 3
parent for above child X: 7 Y: 2
parent for above child X: 6 Y: 1
parent for above child X: 5 Y: 0
parent for above child X: 19 Y: 9
parent for above child X: 18 Y: 8
parent for above child X: 17 Y: 7
parent for above child X: 6 Y: 0
parent for above child X: 10 Y: 4
parent for above child X: 11 Y: 4
parent for above child X: 10 Y: 3
end index: x 9 y 2
但是,当我取消注释调用checkPath(&end, map);
的行(这是在if条件下if(best.getValue() == 3)
下main.cpp的顶部附近)时,我得到了这样的输出:(我已经删除了"parent for above child"的输出)
Start index: x 0 y 19
9 2
9 2
9 2
9 2
9 2
9 2
9 2
和这些9 2打印永远继续,我认为问题是在 printPath
功能我试过调试它,但我看不出我做错了什么。
欢呼,克里斯。
我改变了如何在列表和向量中处理和存储Node*而不是Node Objects的实现,以及在创建时使用new关键字。这解决了我的问题我的A*现在可以工作了
相关文章:
- BFS 打印最短路径
- 如何打印 BFS 路径本身而不是此单词梯的路径长度?
- 用Dijkstra打印出第二短路径的路径.以及第二第二路径
- 打印出矩阵中最长的增加路径
- 使用BFS存储和打印最短路径
- 使用动态规划在矩阵中的所有可能路径中具有最小总和的打印路径
- 在带有转义反斜杠的窗口上打印加速路径
- 在无向图中打印最长的路径
- 如何使用递归来查找和打印从A点到B点的多条最短路径?(C++)
- C++字符串到字符串打印不正确,无法获取 unicode 路径
- C 获取目录路径,解析文件夹名称和来自Parent Directory的打印文件内容
- 打印与BST的直径相对应的节点所包含的路径
- 矩阵遍历打印所有和最短路径 - 无限循环
- 全局声明QStringlist变量,使用QFileDialog获取位置路径并将其打印到lineEdit并在QProces
- 如何使用Qt Windows中的设置路径属性从命令行运行应用程序(.exe)时在命令行上打印日志
- 使用改进的弗洛伊德战争打印最短路径黑白给定节点
- 通过文本迷宫打印到屏幕路径的算法
- 计数/打印路径 - 从 (1,1) 到 (m, n)
- 最短路径,无左转弯,打印路径
- c++在通过A*搜索找到路径后,打印路径会持续打印相同的Nodes信息