「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战」。
算法简介
()算法是一种启发式搜索算法,主要实现对图的路径搜索。算法基于(广度优先搜索),由于具有盲目性,会进行许多偏离最佳路径的搜索,故此算法主要目的就是克服的盲目性,在进行光度搜索时有目的的选择搜索结点。
算法思想
在学习算法之前,首先需要引入评估函数,它用于评估搜索点的优先级。
其中,是搜索点的优先级,越小优先级越高。表示从起点到点的已花费代价。表示点到终点的估计代价。
回顾
是广度优先搜索,他通常采用一个队列,每次从队首读入访问一个点,并把他连接的为访问点放入队尾,直到队列为空。的模板如下:
void BFS(int k){
queue<int> Q;
Q.push(k);//将点k入队
visit[k]=1;//标记已访问k
while(!Q.empty()){
int u=Q.front();Q.pop();//出队
visit[u]=1;//标记u已访问
if(u==end){//找到终点
//得到结果的相关操作;
}
for(int i=head[u];i;i=last[i]){//访问u连接的结点
int v=to[i];//v是u连接的结点编号
if(!visit[v]){
Q.push(v);
}
}
}
}
引入
算法所做的工作就是修改队列的逻辑,因为我们要按优先级访问,所以需要使用优先队列。在当中,可以直接用优先队列,存入顶点可以用来存取,表示优先级,表示顶点编号,因为默认比较逻辑是按照第一个值来比较,所以第一个应该是优先级。
void Astar(int k){
typedef pair<int,int> pir;
priority_queue<pir,vector<pir>,greater<pir> > Q;//因为优先队列默认是大根堆,所以要修改一下比较逻辑
Q.push(make_pair(0,k));//将点k入队,优先级0最高
visit[k]=1;//标记已访问k
while(!Q.empty()){
int u=Q.front().first;Q.pop();//出堆
visit[u]=1;//标记u已访问
if(u==end){//找到终点
//得到结果的相关操作;
}
for(int i=head[u];i;i=last[i]){//访问u连接的结点
int v=to[i];//v是u连接的结点编号
if(!visit[v]){
Q.push(make_pair(f(v)+g(v),v));//v和v的评估入堆
}
}
}
}
关于和
一般来说,评估起点到的距离可以通过搜索过程计算出来,到终点的距离可以通过反向等等单源最短路径算法作为参考值。更一般的,可以使用曼哈顿距离、对角距离、欧氏距离等等来评估。
应用
部分游戏的寻路算法就是用了,除此之外,还可以用来求解短路问题,当第次搜索找到终点时,即为短路。但在一般情况下,只能找到较优解,而不一定是最优解。