a*是一種啟發式搜尋演算法,又叫最佳圖搜尋演算法。
眾所周知,計算機在執行搜尋演算法時是沒開上帝視角的。因此,在搜尋時,往往顯得盲目,把所有可能的狀態全部遍歷,這種搜尋我們統稱盲目搜尋。
我們需要給計算機一些啟發資訊。不同的啟發資訊有不同的強度,既不能太強也不能弱,太強會導致得不到正解,而太弱又會導致優化效果不明顯。都說了這麼多了,那就來點具體的。
在a*之前,首先要提一下a演算法,a*是a的一種特殊情形。
這裡我們要引入乙個函式——「估價函式」。
定義乙個函式\(f(n)=g(n)+h(n)\),利用啟發資訊計算出\(h\),根據\(f\)函式的值找出當前搜尋狀態下的最有希望的節點進行擴充套件。其中\(n\)是乙個狀態,\(f\)就是估價函式,\(g\)是\(n\)已經用掉的開銷(可以理解做裸的bfs用到的資訊),\(h\)是乙個啟發函式。
啟發函式在不同的情況下是有不同的計算方法的,這要因情況而異。
為了更好定義a*演算法,我們還要引入一些函式:\(f^ *(n),g^ *(n),h^ *(n)\)。
首先我們要明確,上面提到的估價函式,是對待擴充套件節點的乙個「估計」,是從啟發資訊計算而來的,因此從初始狀態到正解對應的狀態的花費不是實際花費。
\(f^ *(n)=g^ *(n)+h^ *(n)\)表示的是從搜尋的起點經過\(n\)狀態到達搜尋目標的實際最小花費,因此,你可以把\(f(n),g(n),h(n)\)看作這些帶*的函式的估計值。
a*演算法定義為保證\(h(n)的a演算法,其保證能得到最優解。
在3×3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是:給出一種初始布局(初始狀態)和目標布局(為了使題目簡單,設目標狀態為123804765),找到一種最少步驟的移動方法,實現從初始布局到目標布局的轉變。
顯然這題可以用雙向bfs做(起點狀態和中點狀態模式相同),而且實際上裸的bfs這題也能過。。。
不過既然是在講a*,就討論a*怎麼解(哇,發現題解有一篇我校巨佬的ida*qwq)。
為了使得\(h\)函式一定比\(h^ *(n)\)小,我們考慮構造乙個這樣的函式。在起始狀態,\(h ^*(n)\)顯然就是所有位置的數移動到目標狀態的位置的所需步數。我們可以假定\(h(n)\)為\(n\)狀態時不在目標位置的數的個數。因為顯然,這些不再目標位置的數至少要通過一次移動才能到達目標位置。這是乙個可行方案。
貼**:
用了乙個map來去除重複狀態,其實matrix結構體裡面隨便咋過載都行,反正裝的進去map就行。
#include#include#include#include#include#include#include#include#include#includeusing namespace std;
int dir[4][2]=,,,};
struct matrix
q.push(node(f,0));
while(q.size())
if(mp[x.a]) continue;
mp[x.a]=1;
int nx,ny;
for(int i=1;i<=3;++i)
for(int j=1;j<=3;++j)
if(!x.a.a[i][j]) nx=i,ny=j;
for(int i=0;i<4;++i)
} }return 0;
}
如果要加id的話會更快,這裡不詳細講,具體做法跟一般idbfs是一樣的。
跟上面這道題完全一樣,沒區別,稍微改一下**就好了。
#include#include#include#include#include#include#include#include#include#include#define ll long long
using namespace std;
int dir[8][2]=,,,,,,,};
struct matrix
bool flag=0;
q.push(node(f,0));
while(q.size())
if(!h(x.a)&&!flag)
if(mp[x.a]) continue;
mp[x.a]=1;
int nx,ny;
for(int i=1;i<=5;++i)
for(int j=1;j<=5;++j)
if(x.a.a[i][j]==-1) nx=i,ny=j;
for(int i=0;i<8;++i)
}} }
return 0;
}
就是跑的比較慢啦。 A 搜尋演算法
啟發式搜尋演算法 要理解 a 搜尋演算法,還得從啟發式搜尋演算法開始談起。所謂啟發式搜尋,就在於當前搜尋結點往下選擇下一步結點時,可以通過乙個啟發函式 來進行選擇,選擇代價最少的結點作為下一步搜尋結點而跳轉其上 遇到有乙個以上代價最 少的結點,不妨選距離當前搜尋點最近一次展開的搜尋點進行下一步搜尋 ...
A 搜尋演算法
a 演算法是基於bfs的一種入門級啟發式搜尋演算法,就是將bfs的佇列改為基於估價的優先佇列,可以快速地找到答案。優先隊列為小根堆 while 優先佇列不為空 取出隊頭並擴充套件 將擴充套件節點以估價值 當前值為優先順序入隊 endwhile估價函式越接近真實值演算法越優,但一定不能大於真實值,否則...
搜尋演算法小結
搜尋演算法是利用計算機的高效能來有目的的窮舉乙個問題的部分和所有的可能情況,從而求出問題的解的一種方法。常用的搜尋演算法有 一.回溯法 回溯演算法是所有搜尋演算法中最為基本的一種演算法,其採用了一種 走不通就掉頭 思想作為其控制結構,其相當於採用了先根遍歷的方法來構造解答樹,可用於找解或所有解以及最...