• 双向广度优先搜索


    双向广度优先搜索

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

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

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

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

    假设一个节点能扩展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)

  • 相关阅读:
    Java学习——文件和IO流
    Java多线程——ThreadLocal类的原理和使用
    Java多线程——线程八锁案例分析
    Django 模版语法 一
    Django 命令行调用模版渲染
    Django 使用 locals() 函数
    Django 加载 app 中的urls
    Django 传递额外参数及 URL别名
    Django 无名参数与有名参数
    Django 项目中添加静态文件夹
  • 原文地址:https://www.cnblogs.com/-Iris-/p/12895943.html
Copyright © 2020-2023  润新知