广度优先搜索算法

        在深度优先搜索中,深度越大的结点越先得到扩展。如果把它改为深度越小的结点越先得到扩展,就是广度优先搜索法。

广度优先搜索算法的基本思想:

(1)建立一个空的状态队列SS;

(2)建立一个空的状态库SB;

(3)把初始状态S(0)存入队列SS中;

(4)若队列状态是目标状态,则搜索成功,算法运行中止。如该状态的形式为S(path),则解就是(path);

(5)若某种搜索极限已经达到(如空间用完等),则搜索失败,算法运行结束,没有解;

(6)按某种原则取一个可以应用于SS第一个状态S(path)并产生合适的新状态的规则Rn,产生新状态T(path,n),并将其置于SS的最后,转(4)。若扩展失败,即没有新状态产生,则将SS中第一个状态从SS中除去,送入SB中,执行下步;

(7)若SS成为空队列,则搜索失败,算法运行结束,没有解。否则转(5)。

注:在实际解题中,算法可能有许多不同的变型,要视具体情况应变。下给出算法可供参考:

广度优先基本算法如下:

program BFS;

初始化;建立数据库data;初始状态存入数据库;

设队列首指针closed:=0;队列尾指针open:=1;

repeat

取下一个closed所指结点;

for r:=1 to rmax do {r为产生规则编号}

begin

if 子结点符合条件 then

begin

open增1,把新结点存入数据库队尾;

if 新结点与原有结点重复 then

删去该结点(open减1)

else

if 新结点即目标 then 输出并退出;

end

end

until closed>=open{队列空};

广度优先搜索的显著特点是,在产生新的子结点时,深度越小的越得到优先扩展,即先产生它的子结点。当结点到根结点的费用和结点的深度成正比,特别是当每一结点到根结点的费用等于深度值时,用广度优先得到的解一定是最优解。但只要将上述算法进行改进也可以求得最优解,这就成了代价优先搜索。

下面是一个24点程序的代码:

 

#include  <iostream> 

#include  <string> 

#include  <cmath> 

 

using  namespace  std; 

 

const  double  PRECISION  =  1E-6; 

const  int  COUNT_OF_NUMBER    =  4; 

const  int  NUMBER_TO_BE_CAL  =  24; 

 

double  number[COUNT_OF_NUMBER]; 

string  expression[COUNT_OF_NUMBER]; 

 

bool  Search(int  n) 

       if  (n  ==  1)  { 

               if  (  fabs(number[0]  -  NUMBER_TO_BE_CAL)  <  PRECISION  )  { 

                       cout  <<  expression[0]  <<  endl; 

                       return  true; 

               }  else  { 

                       return  false; 

               } 

       } 

 

       for  (int  i  =  0;  i  <  n;  i++)  { 

               for  (int  j  =  i  +  1;  j  <  n;  j++)  { 

                       double  a,  b; 

                       string  expa,  expb; 

 

                       a  =  number[i]; 

                       b  =  number[j]; 

                       number[j]  =  number[n  -  1]; 

 

                       expa  =  expression[i]; 

                       expb  =  expression[j]; 

                       expression[j]  =  expression[n  -  1]; 

 

                       expression[i]  =  '('  +  expa  +  '+'  +  expb  +  ')'; 

                       number[i]  =  a  +  b; 

                       if  (  Search(n  -  1)  )  return  true; 

                        

                       expression[i]  =  '('  +  expa  +  '-'  +  expb  +  ')'; 

                       number[i]  =  a  -  b; 

                       if  (  Search(n  -  1)  )  return  true; 

                        

                       expression[i]  =  '('  +  expb  +  '-'  +  expa  +  ')'; 

                       number[i]  =  b  -  a; 

                       if  (  Search(n  -  1)  )  return  true; 

                                                

 

                       expression[i]  =  '('  +  expa  +  '*'  +  expb  +  ')'; 

                       number[i]  =  a  *  b; 

                       if  (  Search(n  -  1)  )  return  true; 

 

                       if  (b  !=  0)  { 

                               expression[i]  =  '('  +  expa  +  '/'  +  expb  +  ')'; 

                               number[i]  =  a  /  b; 

                               if  (  Search(n  -  1)  )  return  true; 

                       }   

                       if  (a  !=  0)  { 

                               expression[i]  =  '('  +  expb  +  '/'  +  expa  +  ')'; 

                               number[i]  =  b  /  a; 

                               if  (  Search(n  -  1)  )  return  true; 

                       } 

 

                       number[i]  =  a; 

                       number[j]  =  b; 

                       expression[i]  =  expa; 

                       expression[j]  =  expb; 

               } 

       } 

       return  false; 

 

void  main() 

       for  (int  i  =  0;  i  <  COUNT_OF_NUMBER;  i++)  { 

               char  buffer[20]; 

               int    x; 

               cin  >>  x; 

               number[i]  =  x; 

               itoa(x,  buffer,  10); 

               expression[i]  =  buffer; 

       } 

 

       if  (  Search(COUNT_OF_NUMBER)  )  { 

               cout  <<  "Success."  <<  endl; 

       }  else  { 

               cout  <<  "Fail."  <<  endl; 

       }                 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值