poj 2449 Remmarguts' Date(第K短路 A*)
阿新 • • 發佈:2019-02-01
(注:以下部份資料來源於網上)
所謂A*就是啟發是搜尋 說白了就是給搜尋一個順序使得搜尋更加合理減少無謂的搜尋. 如何來確定搜尋的順序?..也就是用一個值來表示 這個值為f[n]..每次搜尋取f[x]最小的拓展 那麼這個f[n]=h[n]+g[n]
其中f(n) 是節點n的估價函式,g(n)是在狀態空間中從初始節點到n節點的實際代價,h(n)是從n到目標節點最佳路徑的估計代價。在這裡主要是h(n)體現了搜尋的啟發資訊,因為g(n)是已知的。如果說詳細 點,g(n)代表了搜尋的廣度的優先趨勢。但是當h(n) >> g(n)時,可以省略g(n),而提高效率。
A*演算法的估價函式可表示為:
f’(n) = g’(n) + h’(n)
這裡,f’(n)是估價函式,g’(n)是起點到終點的最短路徑值,h’(n)是n到目標的最短路經的啟發值。由於這個f’(n)其實是無法預先知道的,所以我們用前面的估價函式f(n)做近似。g(n)代替g’(n),但g(n)>=g’(n)才可(大多數情況下都是滿足的,可以不用考慮),h(n)代替h’(n),但h(n)<=h’(n)才可(這一點特別的重要)。可以證明應用這樣的估價函式是可以找到最短路徑的,也就是可採納的。我們說應用這種估價函式的最好優先演算法就是A*演算法。
下面以這道題為例,結合著理解相信你就能理解了!!
//9856K
#include <stdio.h>
#include <string.h>
#include <queue>
#define M 100010
#define N 1005
const int inf = 0x3f3f3f3f;
using namespace std;
struct E //鄰接表建邊,to是下個結點,w 是權值 nxt 是下條邊的位置
{
int to,w,nxt;
}edge[2*M];
struct data //g 表示起點到當前點的距離,h表終點到當前點的距離
{
int g,h;
int to;
bool operator < (data a) const
{
return a.h + a.g < h + g;
}
};
int e,n,src,des,head[N],tail[N],dis[N];//head 是正向邊,tail是逆向邊 dis是des(終點)到各點的距離
void addedge (int cu,int cv,int cw)
{
edge[e].to = cv;
edge[e].w = cw;
edge[e].nxt = head[cu];
head[cu] = e ++;
edge[e].to = cu;
edge[e].w = cw;
edge[e].nxt = tail[cv];
tail[cv] = e ++;
}
void dij () //dijstra演算法求des到各點的距離 用於估價函式h
{
int i,j,k;
int vis[N];
memset (vis,0,sizeof(vis));
memset (dis,0x3f,sizeof(dis));
dis[des] = 0;
for (i = 1;i <= n;i ++)
{
k = -1;
int min = inf;
for (j = 1;j <= n;j ++)
if (!vis[j]&&min > dis[j])
{
k = j;
min = dis[j];
}
// if (k == -1) //因為這裡圖肯定是連通的 可加可不加
// break;
vis[k] = 1;
for (int u = tail[k];u != -1;u = edge[u].nxt)
{
int v;
v = edge[u].to;