日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

搜索 —— 启发式搜索 —— A* 算法

發(fā)布時間:2025/3/17 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 搜索 —— 启发式搜索 —— A* 算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【概述】

A*(A-Star)算法是一種在靜態(tài)路網(wǎng)中,求解最短路的最有效的直接搜索方法,也是解決許多搜索問題的有效算法之一。

A* 算法實(shí)際上是對 Dijkstra 算法的優(yōu)化后得到的,關(guān)于 Dijkstra 算法:點(diǎn)擊這里

A*算法在程序設(shè)計(jì)競賽中,一般用于解決 k 短路問題,關(guān)于 k 短路問題:點(diǎn)擊這里

【原理】

在 Dijkstra 算法中,我們借助優(yōu)先隊(duì)列來實(shí)現(xiàn),每次從優(yōu)先隊(duì)列中取出結(jié)點(diǎn),再從這個結(jié)點(diǎn)擴(kuò)散到其他結(jié)點(diǎn),而優(yōu)先隊(duì)列的優(yōu)先依據(jù)是根據(jù)起點(diǎn)到隊(duì)列中結(jié)點(diǎn)最近的一個,即隊(duì)列中的結(jié)點(diǎn)離起始點(diǎn)最近的會先出隊(duì)。

但不可避免的是,Dijkstra 存在跑偏問題,如下圖,若起點(diǎn)為 1 號點(diǎn),終點(diǎn)為 6 號點(diǎn),首先一定會走 3、4 號點(diǎn),這肯定不是最佳路徑,一開始就跑偏了。

在 Dijkstra 算法中,判斷的依據(jù)只是已知的起點(diǎn)到某點(diǎn) i 的距離 G(i),那么我們可以增加一個判斷量來減少跑偏的概率

如果能夠計(jì)算當(dāng)前點(diǎn) i 到終點(diǎn)的距離,再結(jié)合 G(i),那么可以防止過度跑偏,但這個距離是未知的,因此我們可以設(shè)置一個估值,即啟發(fā)函數(shù) H(i)

啟發(fā)函數(shù) H(i) 的設(shè)置是 A* 算法關(guān)鍵,如何設(shè)置這個啟發(fā)函數(shù)影響到算法的性能,在得到了啟發(fā)函數(shù)后,我們就有了最終的估價函數(shù) F(i)=G(i)+H(i),在優(yōu)先隊(duì)列中,以這個估價函數(shù)作為指標(biāo)進(jìn)行出隊(duì)。

一般來說,在二維平面圖中,我們將圖置于坐標(biāo)軸中,通過計(jì)算結(jié)點(diǎn)間的歐幾里得距離來得到兩點(diǎn)間的直線距離,這個距離即可作為當(dāng)前點(diǎn) i 到終點(diǎn)距離的估值。但歐幾里得距離的計(jì)算要進(jìn)行開方,較為復(fù)雜,一般通過加減法來計(jì)算簡單的曼哈頓距離來代替歐幾里得距離,作為啟發(fā)函數(shù) H(i)。

而在一般圖中,我們通常是建立反圖,跑一次最短路算法,將得到每個點(diǎn)到 t?的最短路的距離 dis[i] 作為啟發(fā)函數(shù) H(i)

【實(shí)現(xiàn)】

struct Edge {int to, next;int w;Edge() {}Edge(int to, int next, int w) : to(to), next(next), w(w) {} }; struct Map {int tot;int head[N];Edge edge[N * N];Map() {tot = 0;memset(head, -1, sizeof(head));}void addEdge(int x, int y, int w) {edge[++tot].to = y;edge[tot].next = head[x];edge[tot].w = w;head[x] = tot;}Edge &operator[](int pos) { return edge[pos]; } }; int n, m; Map G, GT; int dis[N]; bool vis[N]; struct Status{int node;//點(diǎn)編號int diss;//距離int priority;//優(yōu)先級Status() : node(0), diss(0), priority(dis[0]) {}Status(int node, int diss) : node(node), diss(diss), priority(diss + dis[node]) {}bool operator<(Status b) const { return priority > b.priority; } } status; bool SPFA(int S, int T) { //對反圖求最短路memset(dis, INF, sizeof(dis));memset(vis, false, sizeof(vis));dis[S] = 0;queue<int> Q;Q.push(S);while (!Q.empty()) {int x = Q.front();Q.pop();vis[x] = false;for (int i = GT.head[x]; i != -1; i = GT[i].next) {int y = GT[i].to;if (dis[x] + GT[i].w < dis[y]) {dis[y] = dis[x] + GT[i].w;if (!vis[y]) {Q.push(y);vis[y] = true;}}}}return dis[T] != INF; } int AStar(int S, int T) {priority_queue<Status> Q;Q.push(Status(S, 0));while (!Q.empty()) {Status temp = Q.top();Q.pop();if (temp.node == T)return temp.diss;for (int i = G.head[temp.node]; i != -1; i = G[i].next)if (temp.diss + G[i].w < temp.diss)Q.push(Status(G[i].to, temp.diss + G[i].w));}return -1; } int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= m; i++) {int x, y, w;scanf("%d%d%d", &x, &y, &w);G.addEdge(x, y, w);GT.addEdge(y, x, w);}int s, t;scanf("%d%d", &s, &t);if (!SPFA(t, s))printf("-1\n");elseprintf("%d\n", AStar(s, t));return 0; }

?

總結(jié)

以上是生活随笔為你收集整理的搜索 —— 启发式搜索 —— A* 算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。