A 搜尋演算法,poj1077 八數碼

2022-05-17 17:24:06 字數 1756 閱讀 6868

今天看了a*搜尋演算法,聽說牛逼的很,不過關鍵還是在於它的評估函式,估計也不一定每題都能這麼容易想吧

就**來說吧,s,儲存所有所搜到的結點的資訊,包括空格位置,深度及評估值,這裡不給出h是因為h一直在變,b儲存開始結點資訊,visited儲存是否訪問到,接下來方向,答案,heap是為了提速而寫的堆實現的優先佇列,nali是為了區別出是否入隊

整個過程:1,開始結點初始化,入佇列並判斷是否為目標,是就輸出,結束

2,取出隊中優先順序即f最小的結點 ,進行擴充套件

3,各個可擴充套件出來的結點,先求雜湊值,判重,如果重複,並還在佇列中,就保留優先順序較小的那個

4,如果沒重複就入隊

5,判斷是否為目標,是就輸出,結束;否則回到2

**

#include#include

#include

#define size 400000

struct

node

s[400000

],b;

int visited[400000],dir[4]=,ans[400000],found;//

0上1下2左3右,

int f[8]=;

int heap[400000],hlength,nali[400000];//

nali中儲存在**,0表示沒在隊裡,1表示在佇列裡

char end[10]=;

void down(int p)//

刪除後向下調整

}heap[p]=a;//

還原原來的點

}int

min()

void up(int p)//

插入後向上調整

heap[p]=a;//

還原原來的點

} void insert(inta)

int hx(char str)//

計算h(x)函式值,計算當前狀態下還未達到正確位置的個數

intget(char str) //

計算全排列雜湊值

return

ret;

} void print(int x)//

若發現可完成,則利用父節點逐個輸出

while (top!=0

)

top--;

}printf("\n

");} void

abfs()

for(i=0;i<4;i++)

//當出現了還在佇列中未出列的,保留f較小的那個

continue

; }

else

if(visited[hash]==0

)

if(strcmp(s[hash].str,end)==0

)

} } int

astar()

}int

main()

else a[j++]=a[i];

}a[j]='\0'

; strcpy(b.str,a);

b.k=m;

found=0;//

標誌變數初始化

//printf("m=%d %s\n",b.k,b.str);

astar();

if(found==0

) printf(

"unsolvable\n");

}//system("pause");

return0;

}

view code

poj 1077 八數碼難題

終於自己ac了這道八數碼難題,用的方法是最最普通的單項bfs hash,這裡主要的難點在於如何儲存狀態,其實,在八數碼裡所有的狀態共有9!種 362880種,所以在每個轉台節點,我需要乙個char state 3 3 來記錄當前棋盤的狀態,用乙個int x,y來記錄當前x的位置,用char oper...

POJ1077 經典的八數碼問題

很經典的八數碼問題,可以用單向廣度優先搜尋 雙向廣度優先搜尋 a 演算法 ida演算法解。用了雙向廣度優先搜尋和a 演算法解,在用a 演算法時,糾結了好幾天,後來在網上看了乙份部落格才發現自己錯在哪。之後解出來了。雖然做這題時很糾結,不過收穫真的很大,痛而快樂著 下面貼出用雙向廣度優先搜尋和a 演算...

poj 1077 Eight A 解八數碼問題

題意 經典的八數碼問題。分析 搜尋演算法的區別是如何重排open表,關鍵是如何編碼狀態和定義狀態的值。對搜尋過程中任意狀態s,a 演算法以g s h s 重排open表,也就是說g s h s 是排列open中狀態的依據,其中g s 是初始狀態到s的消耗,h s 是s到目標狀態的估計。我重排open...