双向广度优先搜索

 

双向广度优先搜索

双向广度优先搜索是对广搜算法的一种扩展。广搜以起点以广度优先的顺序不断扩展,直到遇到目的节点。

而双向广搜算法从两个方向开展广搜,一个从起点,另一个从终点。

直到一个扩展队列中出现了另一个队列中已经扩展了的点,也就是说两个扩展方向出现了交点。

 

双向广搜相对于广搜算法来说,由于采用了双向同时扩展的方式,搜索树的宽度明显减宽,时间和空间复杂度都明显提高。

 

假设一个节点能扩展n个节点,扩展m层,单向广搜扩展出的数量就是    (1 - nm) ⁄ ( 1 - n )

而双向广搜同样扩展m层,总结点数为   ( 1 - nm/2) / ( 1 - n ) ,在数据范围较大的时候,优势就体现出来了

 

 1 void dbfs{
 2     将起点放入队列q1,目标节点放入q2
 3     while(两个队列均未空且未发现路径){
 4            如果q1中节点比q2中少,则扩展q1,否则扩展q1
 5     }
 6     if(未发现路径){
 7        如果q1未空,不断扩展q1为空或发现路径
 8        如果q2未空,不断扩展q2未空或发现路径
 9     }
10 }

 

现在我插入一段关于八数码问题的双向广搜代码

 1 inline bool DBFs(int status)
 2 {
 3 \\寻找初始状态status到目标的路径,找不到则返回false
 4     int newstatus;
 5     set<int> expanded[2];\\两个队列判重
 6     for(int i=0;i<2;i++){
 7         qhead[i]=0;qtail[i]=1;
 8     }
 9     myqueue[0][0]=Node(status,-1,0);
10     expanded[0].insert(status);
11     myqueue[1][0]=Node(goalStatus,-1,0);
12     expanded[1].insert(goalStatus);
13     while(qhead[0]!=qtail[0]&&qhead[1]!=qtail[1])\\两队均不为空
14     {
15         int qno;\\本次要扩展的队列
16         if(qhead[0]==qtail[0]) qno=1;
17         else if(qhead[1]=qtail[1])
18         qno=0;
19         else{//比较两队元素个数
20             if(qtail[0]-qhead[0]<qtail[1]-qhead[1])
21             qno=0;
22             else qno=1;
23         }
24         int vqno=1-qno;//另一队列
25         status=myqueue[qno][qhead[qno]].Status ;
26         if(expanded[vqno].find(status)!=expanded[vqno].end()  ){//在另一个队列扩展过,路径找到            matchings=status;
27             matchingq=qno;
28             return true;
29         }
30         else{
31             for(int i=0;i<4;i++){//尝试4种移动
32                 newstatus=New(status,move[i]); //表示移动后的新状态是否可行
33                 if(newstatus==-1)
34                 continue;//否,下一种
35                 if(expanded[qno].find(newstatus)!=expanded[qno].end() )
36                 continue;//以扩展过,则不能入队
37                 expanded[qno].insert(newstatus);
38                 myqueue[qno][qtail[qno]]=Node(newstatus,qhead[qno],moves[i]);//moves[]表示4种移动
39                 qtail[qno]++; 
40             }
41             qhead[qno]++;
42         }
43       }  
44       return false;
45 }

其中 goalstatus 为目标状态   matchings为双向碰到的状态  matchingq碰到的那个队列

 

-end-

 

强行退出函数 exit(0)

 

posted @ 2020-05-17 16:12  ·Iris  阅读(668)  评论(7编辑  收藏  举报