A*算法是比较流行的启发式搜索算法之一,被广泛应用于路径优化领域[。它的独特之处是检查最短路径中每个可能的节点时引入了全局信息,对当前节点距终点的距离做出估计,并作为评价该节点处于最短路线上的可能性的量度。
算法思想参考了https://www.cnblogs.com/zhoug2020/p/3468167.htm
想了解主要算法思想可以参考上述博客,很好理解。
具体实现代码如下
// AStarArithmetic.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include <Vector>
using namespace std;
struct Pos
{
int x;
int y;
int F;
};
//分别存放下一步可以走的位置信息和已经走过的位置信息
vector<Pos> open;
vector<Pos> close;
//显示地图信息和运动轨迹
void ShowImage(int *arr, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (*(arr + i * col + j) == 0)
{
cout << "0 ";
}
else if (*(arr + i * col + j) == 1)
{
cout << "* ";
}
else if (*(arr + i * col + j) == 5)
{
cout << "- ";
}
else
{
cout << "+ ";
}
}
cout << endl;
}
}
//获得x2,y2的F 也就是从原点经过x2,y2到终点所走的路程(忽略障碍物)
int GetF(int x1,int y1,int x2,int y2,int x3,int y3)
{
int G = abs(x2 - x1)+ abs(y2-y1);
int H = abs(x3 - x2) + abs(y3 - y2);
return G + H;
}
//寻找最短路径
void ChoseShortPath(int *arr, int row, int col, int px, int py,int nowx,int nowy, int dx, int dy)
{
if (nowx == dx && nowy == dy)
{
return;
}
if (nowx-1>=0)
{
if (*(arr + col * (nowx - 1) + nowy)==0)
{
Pos p;
p.x = nowx - 1;
p.y = nowy;
p.F = GetF(px, py, p.x, p.y, dx, dy);
//添加过的设置为2
*(arr + p.x * col + p.y) = 2;
open.push_back(p);
}
}
if (nowx + 1 < row)
{
if(*(arr + col * (nowx + 1) + nowy) == 0)
{
Pos p;
p.x = nowx + 1;
p.y = nowy;
p.F = GetF(px, py, p.x, p.y, dx, dy);
*(arr + p.x * col + p.y) = 2;
open.push_back(p);
}
}
if (nowy - 1 >= 0)
{
if (*(arr + col * nowx + nowy -1) == 0)
{
Pos p;
p.x = nowx;
p.y = nowy -1;
p.F = GetF(px, py, p.x, p.y, dx, dy);
*(arr + p.x * col + p.y) = 2;
open.push_back(p);
}
}
if (nowy + 1 < col)
{
if (*(arr + col * nowx + nowy + 1) == 0)
{
Pos p;
p.x = nowx;
p.y = nowy + 1;
p.F = GetF(px, py, p.x, p.y, dx, dy);
*(arr + p.x * col + p.y) = 2;
open.push_back(p);
}
}
int minIndex = 0;
for (int index = 1; index < open.size(); index++)
{
if (open[index].F <= open[minIndex].F)
{
minIndex = index;
}
}
nowx = open[minIndex].x;
nowy = open[minIndex].y;
cout << nowx<<","<<nowy<<endl;
//选择过的设置为3
*(arr + nowx * col + nowy) = 3;
//获取该位置元素的迭代器
vector<Pos>::iterator it = open.begin() + minIndex;
close.push_back(open[minIndex]);
//删除该元素
open.erase(it);
ChoseShortPath(arr, row, col, px, py, nowx, nowy, dx, dy);
}
//显示最短路径到二维数组
void ShowShorPathToArr(int *arr, int row, int col, int px, int py)
{
int EndIndex = close.size() - 1;
*(arr + col * close[EndIndex].x + close[EndIndex].y) = 5;
int i = 0;
//应该从前往后找相邻的位置避免绕路
int StartIndex = 0;
while (close[EndIndex].x != px || close[EndIndex].y != py)
{
if (abs(close[StartIndex + i].x - close[EndIndex].x)+abs(close[StartIndex + i].y - close[EndIndex].y)==1)
{
EndIndex = StartIndex + i;
StartIndex = 0;
i = 0;
//将最短路径上的点赋值为5
*(arr + col * close[EndIndex].x + close[EndIndex].y) = 5;
}
else
{
i++;
}
}
}
//场景抽象化成的数组 1代表地形限制
int a[6][7] = { {0,0,0,0,0,0,0},
{0,0,0,1,0,0,0},
{0,0,0,1,0,0,0},
{0,0,0,1,0,0,0},
{0,1,0,1,0,0,0},
{0,0,0,0,0,0,0}
};
int main()
{
ShowImage( *a,6,7);
a[3][1] = 2;
Pos startP;
startP.x = 3;
startP.y = 1;
close.push_back(startP);
ChoseShortPath(*a, 6, 7, 3, 1, 3, 1, 4, 5);
ShowShorPathToArr(*a, 6, 7, 3, 1);
ShowImage(*a, 6, 7);
}