1.狀態圖搜尋
1.1搜尋樹:搜尋過程中經過的節點和邊按原圖的連線關係構成乙個樹型的有向圖,稱為搜尋樹。
1.2搜尋方式
樹式搜尋:記錄搜尋過程中所經過的所有節點和邊
1.3路徑的獲得
樹式搜尋:反向求解
2.搜尋演算法
2.1 closed表和open表
closed表對樹式搜尋來說儲存的是正在成長的搜尋樹,對線式搜尋來說儲存的是不斷伸長的折線,本身就是所求的路徑。
open表儲存當前待考查的節點。
2.2樹式搜尋演算法
步1 把初始節點放入open表;
步2 檢查open表,若為空,則問題無解,退出;
步3 移出open表中第乙個節點n並放入closed表中,並編號為n;
步4 考察節點n是否為目標節點,若是,則搜尋成功,退出;
步5 若n不可擴充套件,則轉步2;
步6 擴充套件節點n,生成所有子節點,對這組子節點作如下處理:
(1)如果有節點n的先輩節點,則刪除;
(2)如果有已存在於open表的節點,也刪除;但刪除之前要比較其返回初始節點的新路徑與原路徑,如果新路徑「短」,則修改這些節點在open表中的原指向父節點的指標,使其指向新的父節點。
(3)如果有已存在於closed表中的節點,則作與(2)同樣的處理,並且再將其移出closed表,放入open表重新擴充套件;
(4)對其餘子節點,配上指向父節點n的指標後放入open表,對open表按某種搜尋策略排序後轉步2。
3.啟發函式
用來估計搜尋樹上節點x與目標節點sg接近程度的函式,記為h(x)。
4.估價函式
f(x)=g(x)+h(x); 其中g(x)是代價函式,h(x)是啟發函式。 或定義為:f(x)=d(x)+h(x); d(x)是x的深度。
1.定義代價函式g(x)和啟發函式h(x),以a演算法進行求解。
2.輸入初始狀態和目標狀態。
3.輸出從初始狀態到目標狀態的路線。
//此**僅可實現簡單的八數碼問題
//把注釋去掉即為a*演算法
#include
#include
#include
#include
#include
#include
using
namespace std;
class
node
;bool
cmp(
const node &s1,
const node &s2),,
};while
(ptr1 !=
null
)while
(ptr2 !=
null
)for
(int i =
0; i <
3; i++)if
(s2.node[i]
[j]!= node[i]
[j])}}
return
(gx1+hx1)
>
(gx2+hx2);}
bool
isequal
(node n1,node n2)
class
a_algorithm
// 判斷是否是目標狀態
intnextnode
(node *s)
;// 下乙個可行的節點
//int cantor(int node[3]); // 康托展開
void
algorithm()
;// a演算法
void
printpath
(node *head)
;// 列印路徑
void
freeclosed
(node *closed)
;// 釋放close表
private
://unsigned char allhash[362880];
node s0;
//初始節點
node sg;
//目標節點
int nextnum;
node next[4]
;//擴充套件節點};
a_algorithm::
a_algorithm
(node *s0, node *sg)
int a_algorithm::
nextnode
(node *s)
if(posi-
1>=0)
*/}if
(posi+
1<=2)
*/}if
(posj-
1>=0)
*/}if
(posj+
1<=2)
*/}return nextnum;}/*
int a_algorithm::cantor(int node[3]);
int index = 0;
for(int i = 7; i >= 0; i--)
}index += (count*fac[8-i]);
}return index;}*/
void a_algorithm::
algorithm()
int nextnum =
nextnode
(n);
//擴充套件n節點,並取n節點的可擴充套件節點數
if(nextnum ==0)
//如果n不可擴充套件則繼續
continue
;for
(int i =
0; i < nextnum; i++)/*
for (int j = 0; j < open.size();j++)}*/
open.
push_back
(next[i]);
sort
(open.
begin()
, open.
end(
), cmp)
;//對open表的節點按照估價函式的值進行從大到小排序,每次取估價函式值最小的節點即表中的最後乙個節點
/* cout << step << " open table:" << endl;
for (int i = 0; i < open.size();i++)
printpath(&open[i]);
*/} cout <<
"failed."
<< endl;
freeclosed
(closed)
;return;}
void a_algorithm::
printpath
(node *head)
else
cout << endl;
} cout <
void a_algorithm::
freeclosed
(node *closed)
}int
main()
,,},
0,null};
//初始化初始節點
node sg =,,
},0,
null};
//初始化目標節點
cout <<
"searchpath: "
<< endl<
a_algorithm
(&s0,
&sg)
.algorithm()
;return0;
}
A 演算法解決八數碼問題(C 版本)
八數碼問題也稱為九宮問題。在3 3的棋盤,擺有八個棋子,每個棋子上標有1至8的某一數字,不同棋子上標的數字不相同。棋盤上還有乙個空格,與空格相鄰的棋子可以移到空格中。要求解決的問題是 給出乙個初始狀態和乙個目標狀態,找出一種從初始轉變成目標狀態的移動棋子步數最少的移動步驟。關鍵之處 要維護兩個結構 ...
C STL解決八數碼問題
先放原始碼 大部分借鑑了書本的 隨後對部分 進行解釋 include include include define len 362880 using namespace std 八數碼問題 struct node int dir 4 2 int vis len long int factory in...
A 演算法解決八數碼問題(C 類改進版)
八數碼問題 在乙個3 3的棋盤中,分別用1,2,3,8表示八個數碼方格,用0表示空缺的方格,現給出乙個初始狀態和目標狀態,尋找出在評估函式f n g n h n 的限制下,以最少的步數到達目標狀態 一次將乙個數碼方格移動到空缺的方格中 其中,g n 表示n節點與目標狀態的 距離 h n 表示n節點與...