启发式搜索(Heuristically Search)又称为有信息搜索(Informed Search),它是利用问题拥有的启发信息来引导搜索,达到减少搜索范围、降低问题复杂度的目的,这种利用启发信息的搜索过程称为启发式搜索。
例题:八数码问题
运用优先队列,根据目前已经确定的位置算出目前的价值,并导入优先队列,出队时价值大的先出队伍
#include<cstdio>
#include<queue>
#include<map>
using namespace std;
char arr[10],aim[10]="123804765";
int des=123804765;
struct node{
int cur; //当前的状态
int step; //步数
int zeroPos;//当前空格的位置
int cost;
bool operator<(const node &a)const{
return cost>a.cost;
}
node(int n,int s,int p)
{
cur=n;
step=s;
zeroPos=p;
setCost();
}
void setCost()
{
char a[10];
int c=0;
sprintf(a,"%09d",cur);
for(int i=0;i<9;i++)
if(a[i]!=aim[i])
c++;
cost=c+step;
}
};
int bfs_direction[9][4]={{-1,-1,3,1},{-1,0,4,2},{-1,1,5,-1},
{0,-1,6,4},{1,3,7,5},{2,4,8,-1},
{3,-1,-1,7},{4,6,-1,8},{5,7,-1,-1}};
map<int,bool>mymap;
priority_queue<node> que;//优先级队列
void swap(char* ch,int a,int b){
char c=ch[a];
ch[a]=ch[b];
ch[b]=c;
}
int BFS(int start,int zeroPos){ //start初始状态 zeroPos初始空格的位置
char temp[10];
node tempN(start,0,zeroPos);//创建一个节点
que.push(tempN);//压入优先级队列
mymap[start]=1;//标记开始节点被访问过
while(!que.empty()){
tempN=que.top();
que.pop();//弹出一个节点
sprintf(temp,"%09d",tempN.cur);
int pos=tempN.zeroPos;
int k;
for(int i=0;i<4;i++){
if(bfs_direction[pos][i]!=-1){
swap(temp,pos,bfs_direction[pos][i]);
sscanf(temp,"%d",&k);
if(k==des)return tempN.step+1;
if(mymap.count(k)==0){
node tempM(k,tempN.step+1,bfs_direction[pos][i]);
que.push(tempM);//创建一个新节点并压入队列
mymap[k]=1;
}
swap(temp,pos,bfs_direction[pos][i]);
}
}
}
}
int main(){
int n,k,b;
scanf("%s",arr); //起始状态
for(k=0;k<9;k++)
{//k空格的位置········
if(arr[k]=='0')
break;
}
sscanf(arr,"%d",&n);//将初始状态化为数字
b=BFS(n,k);
printf("%d",b);
return 0;
}