启发式搜索

启发式搜索(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值