A*算法在最短路问题的应用及其使用举例
?
?
?
1 A*算法
????A*算法在人工智能中是一種典型的啟發(fā)式搜索算法,啟發(fā)中的估價(jià)是用估價(jià)函數(shù)表示的:
其中f(n)是節(jié)點(diǎn)n的估價(jià)函數(shù),g(n)表示實(shí)際狀態(tài)空間中從初始節(jié)點(diǎn)到n節(jié)點(diǎn)的實(shí)際代價(jià),h(n)是從n到目標(biāo)節(jié)點(diǎn)最佳路徑的估計(jì)代價(jià)。另外定義h'(n)為n到目標(biāo)節(jié)點(diǎn)最佳路徑的實(shí)際值。如果h'(n)≥h(n)則如果存在從初始狀態(tài)走到目標(biāo)狀態(tài)的最小代價(jià)的解,那么用該估價(jià)函數(shù)搜索的算法就叫A*算法。
?
2?第K最短路的算法
????我們?cè)O(shè)源點(diǎn)為s,終點(diǎn)為t,我們?cè)O(shè)狀態(tài)f(i)的g(i)為從s走到節(jié)點(diǎn)i的實(shí)際距離,h(i)為從節(jié)點(diǎn)i到t的最短距離,從而滿足A*算法的要求,當(dāng)?shù)贙次走到f(n-1)時(shí)表示此時(shí)的g(n-1)為第K最短路長(zhǎng)度。C++代碼如下:()
CDOJ找的一道例題:(模板題)這里面用到SPFA算法(這是中國(guó)人創(chuàng)造的,用于求單源最短路的一種算法,關(guān)于SFPA時(shí)間復(fù)雜度的問題,,,不確定性,有時(shí)很大,有時(shí)很小,emmmm,貌似外國(guó)人不太認(rèn)可,)
?
?
?
Time Limit: 10000 MS ??? Memory Limit: 256 MB
Submit?Status
6·1即將來臨,游樂園推出了新的主題活動(dòng),雨過天晴,帆寶和樂爺童心未泯,準(zhǔn)備一探究竟。
興奮的他們一入園便和孩子們打成一片,不知不覺便走散了。
當(dāng)他們意識(shí)到的時(shí)候,只能通過手機(jī)來確認(rèn)對(duì)方的位置。
他們當(dāng)然想盡快找到對(duì)方,然而由于孩子們實(shí)在是太多,只能選擇距離稍遠(yuǎn)的但是游客稀少的路會(huì)合。
帆寶希望找到第kk短的路徑,這條路徑是他認(rèn)為的幸運(yùn)路徑。
帆寶迫切地想知道該條路徑的長(zhǎng)度,而樂于助人的你也一定會(huì)幫助她的。
Input
第一行三個(gè)整數(shù)n,m,kn,m,k,分別表示游樂園的景點(diǎn)數(shù)目、景點(diǎn)之間的道路數(shù)目以及路徑長(zhǎng)度從小到大排列時(shí)希望選擇的序號(hào)。
第二行兩個(gè)整數(shù)S,TS,T,分別表示帆寶和樂爺所在景點(diǎn)的編號(hào)。
接下來mm行,每行三個(gè)整數(shù)u,v,wu,v,w,表示編號(hào)為uu和vv的景點(diǎn)之間有一條長(zhǎng)度為ww的單向通路。
1≤n≤1000,0≤m≤100000,1≤k≤1000,1≤S,T,u,v≤N,1≤w≤1001≤n≤1000,0≤m≤100000,1≤k≤1000,1≤S,T,u,v≤N,1≤w≤100
Output
第一行一個(gè)整數(shù)xx,表示所選路徑的長(zhǎng)度
無解輸出?1?1
Sample input and output
| 3 3 2 1 2 1 2 2 1 3 4 3 2 1 | 5 |
?
?
題意:給你起點(diǎn),終點(diǎn)以及要求的第K短路;
題解:首先將有向圖以終點(diǎn)T為起點(diǎn),計(jì)算出T到每一個(gè)邊的最短距離(到第i條邊dis[i]),
然后建立一個(gè)優(yōu)先隊(duì)列,從優(yōu)先隊(duì)列中彈出f(p)最小的點(diǎn)p,如果p就是T,則T的次數(shù)加一。如果當(dāng)前次數(shù)等于K則當(dāng)前路即為地K小
的路,,否則,,便利每一個(gè)p 所連的邊,將其擴(kuò)張出的到p臨接點(diǎn)的信息加入到優(yōu)先隊(duì)列中;
?
AC代碼:
1 #include <bits/stdc++.h> 2 #define INF 0x3f3f3f3f 3 using namespace std; 4 const int AX = 1e5+66; 5 const int MAXN = 1e3+66; 6 int n,m,k; 7 int s,t; 8 int tot; 9 int retot; 10 struct edge{ 11 int to,w; 12 int next1; 13 }G[AX],RG[AX]; 14 15 struct Node{ 16 int v; 17 int f,h,g; 18 bool operator < (const Node &a) const{ return f==a.f? g>a.g : f>a.f; } 19 }; 20 21 22 int dis[MAXN]; 23 int head[MAXN]; 24 int rehead[AX]; 25 int vis[MAXN]; 26 27 void add_edge(int u,int v,int c) 28 { 29 G[tot].to=v; 30 G[tot].w=c; 31 G[tot].next1=head[u]; 32 head[u]=tot++; 33 34 RG[retot].to=u; 35 RG[retot].w=c; 36 RG[retot].next1=rehead[v]; 37 rehead[v]=retot++; 38 } 39 void SPFA() 40 { 41 for(int i=1;i<=n;i++) dis[i]=INF; 42 dis[t]=0; 43 queue<int> Q; 44 Q.push(t); 45 while(!Q.empty()) 46 { 47 int u=Q.front(); 48 Q.pop(); 49 for(int i=rehead[u];i!=-1;i=RG[i].next1) 50 { 51 int v=RG[i].to ; 52 int w=RG[i].w ; 53 if(dis[v]>dis[u]+w) 54 { 55 dis[v]=dis[u]+w; 56 Q.push(v); 57 } 58 } 59 } 60 } 61 62 int Astar(Node a) 63 { 64 memset(vis,0,sizeof(vis)); 65 if(dis[s]==INF) return -1;//如果沒有與S相連的點(diǎn) 66 if(s==t) k++; 67 priority_queue<Node> Q; 68 Q.push(a); 69 while(!Q.empty()) 70 { 71 Node tmp=Q.top(); 72 Q.pop(); 73 int v=tmp.v; 74 vis[v]++; 75 if(vis[t]==k) return tmp.g; 76 for(int i=head[v];i!=-1;i=G[i].next1) 77 { 78 Node p; 79 p.v=G[i].to; 80 p.h=dis[G[i].to]; 81 p.g=tmp.g+G[i].w; 82 p.f=p.g+p.h; 83 Q.push(p); 84 } 85 } 86 return -1; 87 } 88 89 int main() 90 { 91 tot=0; 92 retot=0; 93 memset(head,-1,sizeof head); 94 memset(rehead,-1,sizeof rehead); 95 scanf("%d%d%d",&n,&m,&k); 96 scanf("%d%d",&s,&t); 97 int x,y,w; 98 for(int i=0;i<m;i++) 99 { 100 scanf("%d%d%d",&x,&y,&w); 101 add_edge(x,y,w); 102 } 103 SPFA(); 104 Node a; 105 a.v=s; 106 a.g=0; 107 a.h=dis[s]; 108 a.f=a.g+a.h; 109 int g=Astar(a); 110 printf("%d\n",g); 111 return 0 ; 112 } View Code?
后面我還會(huì)更新出 關(guān)于啟發(fā)式搜索的講解,以及Dijkstra,,SPFA,Folyd這三種關(guān)于不同最短路問題講解及例題分析。
越努力,越幸運(yùn)!? ? 加油!!!
?
轉(zhuǎn)載于:https://www.cnblogs.com/songorz/p/9386760.html
總結(jié)
以上是生活随笔為你收集整理的A*算法在最短路问题的应用及其使用举例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 唐宇迪ocr检测图片
- 下一篇: nuxt2中使用less