深度宽度优先搜索八数码Word文档格式.docx

上传人:b****5 文档编号:19074651 上传时间:2023-01-03 格式:DOCX 页数:18 大小:56.37KB
下载 相关 举报
深度宽度优先搜索八数码Word文档格式.docx_第1页
第1页 / 共18页
深度宽度优先搜索八数码Word文档格式.docx_第2页
第2页 / 共18页
深度宽度优先搜索八数码Word文档格式.docx_第3页
第3页 / 共18页
深度宽度优先搜索八数码Word文档格式.docx_第4页
第4页 / 共18页
深度宽度优先搜索八数码Word文档格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

深度宽度优先搜索八数码Word文档格式.docx

《深度宽度优先搜索八数码Word文档格式.docx》由会员分享,可在线阅读,更多相关《深度宽度优先搜索八数码Word文档格式.docx(18页珍藏版)》请在冰豆网上搜索。

深度宽度优先搜索八数码Word文档格式.docx

(b)=0;

 for(iii=0;

iii <

NUM;

iii++) (b)=((b)<<

4)+ a[iii];

}*///将数组a转换为一个64位的整数b

#define RTRANS(a,b)\

{\

long iii;

UINT64 ttt=(a);

\

for(iii=NUM -1;

 iii>

= 0;

iii--) \

{\

b[iii]=ttt&0xf;

 \

ttt>

>=4;

}\

}//将一个64位整数a转换为数组b

//

typedefstructEP_NODE_Tag

{UINT64v;

 //保存状态,每个数字占4个二进制位,可解决16数码问题

structEP_NODE_Tag*prev;

//父节点

structEP_NODE_Tag*small, *big;

}EP_NODE;

EP_NODEm_ar[MAX_NODE];

EP_NODE*m_root;

longm_depth;

//搜索深度

EP_NODE m_out[MAX_DEP];

//输出路径

longmove_gen(EP_NODE *node,EP_MOVE *move)

{long pz;

//0的位置

UINT64t=0xf;

for(pz=NUM - 1;

pz>=0;

pz--)

{if((node->

v&

t)==0)

{ break;

//找到0的位置

t<<

=4;

}

switch(pz)

{case0:

move[0].x=0;

move[0].y=1;

move[1].x=0;

move[1].y=3;

return2;

case1:

move[0].x=1;

move[0].y=0;

move[1].x=1;

move[1].y=2;

move[2].x=1;

move[2].y=4;

return3;

case2:

move[0].x=2;

move[0].y=1;

move[1].x=2;

move[1].y=5;

return 2;

case 3:

move[0].x=3;

move[0].y=0;

move[1].x=3;

move[1].y=6;

move[2].x=3;

move[2].y=4;

return3;

case 4:

move[0].x=4;

move[0].y=1;

move[1].x=4;

move[1].y=3;

move[2].x=4;

move[2].y=5;

move[3].x=4;

move[3].y=7;

return4;

case5:

move[0].x=5;

move[0].y=2;

move[1].x=5;

move[1].y=4;

move[2].x=5;

move[2].y=8;

return3;

case6:

move[0].x=6;

move[0].y=3;

move[1].x=6;

move[1].y=7;

return 2;

case7:

move[0].x=7;

move[0].y=6;

move[1].x=7;

move[1].y=4;

move[2].x=7;

move[2].y=8;

case8:

move[0].x=8;

move[0].y=5;

move[1].x=8;

move[1].y=7;

return2;

return0;

long mov(EP_NODE*n1, EP_MOVE*mv,EP_NODE *n2)

//走一步,返回走一步后的结果

charss[NUM];

RTRANS(n1->v,ss);

XCHG(ss[mv->

x],ss[mv->

y]);

TRANS(ss,n2->

v);

return 0;

longadd_node(EP_NODE*node, longr)

EP_NODE*p=m_root;

EP_NODE*q;

while(p)

{q=p;

if(p->

v==node->

v) return0;

elseif(node->

v>

p->

v)p=p->

big;

elseif(node->v<

p->

v)p=p->

small;

m_ar[r].v=node->

v;

m_ar[r].prev=node->prev;

m_ar[r].small=NULL;

m_ar[r].big=NULL;

if(node->

v >

q->

v)

{q->

big=&

m_ar[r];

else if(node->

v<

q->v)

{q->

small=&m_ar[r];

return 1;

/*得到节点所在深度*/

longget_node_depth(EP_NODE*node)

{long d=0;

while(node->

prev)

{d++;

node=node->

prev;

returnd;

/*返回值:

成功-返回搜索节点数,节点数不够-(-1),无解-(-2)*/

long bfs_search(char*begin,char*end)

{long h=0,r=1, c,i,j;

EP_NODE l_end,node,*pnode;

EP_MOVE mv[4];

//每个局面最多4种走法

TRANS(begin,m_ar[0].v);

TRANS(end,l_end.v);

m_ar[0].prev=NULL;

m_root=m_ar;

m_root->

small=NULL;

m_root->

big=NULL;

while((h<r) &

&

(r<

 MAX_NODE- 4))

{c=move_gen(&

m_ar[h],mv);

for(i=0;

 i<

c;

i++)

{mov(&

m_ar[h],&

mv[i],&node);

node.prev= &

m_ar[h];

if(node.v== l_end.v)

{ pnode=&node;

j=0;

while(pnode->

prev)

{m_out[j]=*pnode;

j++;

pnode=pnode->prev;

m_depth=j;

returnr;

if(add_node(&

node,r))r++;

//只能对历史节点中没有的新节点搜索,否则会出现环

h++;

printf("

\rSearch...%9d/%d@ %d"

h,r,get_node_depth(&

m_ar[h]));

if(h==r)

{return-2;

 }

else

{return-1;

longcheck_input(char*s,chara, longr)

{ longi;

for(i=0;

i<

r;

 i++)

{ if(s[i]== a - 0x30)return0;

return1;

long check_possible(char*begin,char*end)

{char fs;

longf1=0,f2=0;

long i,j;

for(i=0;

 i <

NUM;

 i++)

{fs=0;

for(j=0;

j<

 i;

j++)

if((begin[i]!

=0)&

(begin[j]!

= 0)&

&(begin[j]<

begin[i]))fs++;

f1+=fs;

fs=0;

for(j=0;

j<i;

j++)

{if((end[i] !

=0) &&

 (end[j]!

=0) &

(end[j] <

end[i]))fs++;

f2+=fs;

if((f1&

1)== (f2&

1))return1;

return0;

voidoutput(void)

{ longi, j, k;

charss[NUM];

for(i=m_depth-1;

i>

=0;

 i--)

{RTRANS(m_out[i].v,ss);

for(j=0;

j<

SIZE;

j++)

{for(k=0;

 k<

 SIZE;

k++)

{printf("

%2d"

ss[SIZE* j+k]);

printf("

\n"

);

printf("

);

intmain(void)

{ char s1[NUM];

chars2[NUM];

long r;

char a;

printf("请输入开始状态:

"

r=0;

while(r <

NUM)

{ a=getchar();

if(a>=0x30&

&a <

0x39 &

 check_input(s1, a,r))

{s1[r++]=a-0x30;

printf("

%c"

a);

printf("\n请输入结束状态:

r=0;

while(r<

NUM)

{a=getchar();

if(a>

=0x30&

a<

 0x39&

&check_input(s2,a,r))

{ s2[r++]=a-0x30;

if(check_possible(s1,s2))

{r=bfs_search(s1, s2);

printf("

\n");

if(r>

=0)

{printf("查找深度=%d,所有的方式=%ld\n"

 m_depth, r);

output();

elseif(r ==-1)

{printf("

没有找到路径.\n"

elseif(r==-2)

{printf("

这种状态变换没有路径到达.\n"

{printf("不确定的错误.\n"

else

{ printf("

不允许这样移动!

\n");

return0;

方法二:

用MATLAB实现

program8no_bfs;

      {八数码的宽度优先搜索算法}

Const

Dir:

array[1..4,1..2]ofinteger{四种移动方向,对应产生式规则}

  =((1,0),(-1,0),(0,1),(0,-1));

 n=10000;

Type

  T8no =array[1..3,1..3]ofinteger;

 TList=record

Father :

 integer;

   {父指针}

 dep:

byte;

   {深度}

X0,Y0:

byte;

     {0的位置}

State:

T8no;

 {棋盘状态}

 end;

Var

Source,Target:

 T8no;

List :

 array[0..10000]ofTList;

{综合数据库 }

 Closed,open,Best:

integer {Best表示最优移动次数}

Answer:

 integer;

  {记录解}

 Found:

Boolean;

     {解标志}

  procedure GetInfo;

        {读入初始和目标节点}

var i,j:

integer;

 begin

  for i:

=1 to3do

 forj:

=1to3do read(Source[i,j]);

fori:

=1to 3do

  forj:

=1 to 3doread(Target[i,j]);

procedure Initialize;

     {初始化}

 varx,y:

integer;

 begin

 Found:

=false;

  Closed:

=0;

open:

=1;

   

withList[1] dobegin

State:

=Source;

dep:

=0;

Father:

=0;

  Forx:

=1to 3do

  For y:

=1to 3do

 ifState[x,y]=0then Beginx0:

=x;

y0:

=y;

End;

 end;

 end;

FunctionSame(A,B :

T8no):

Boolean;

 {判断A,B状态是否相等}

 Var i,j:

integer;

Begin

Same:

=false;

 Fori:

=1to 3doforj:

=1to3do ifA[i,j]<>

B[i,j]thenexit;

 Same:

=true;

End;

Functionnot_Appear(new:

tList):

boolean;

{判断new是否在List中出现}

vari:

integer;

begin

  not_Appear:

=false;

   fori:

=1toopendoifSame(new.State,List[i].State)thenexit;

not_Appear:

=true;

end;

procedureMove(n :

tList;

d:

 integer;

varok :

boolean;

varnew:

tList);

 {将第d条规则作用于n得到new,OK是new是否可行的标志}

 var x,y :

integer;

begin

X :

=n.x0+Dir[d,1];

  Y:

=n.y0 +Dir[d,2];

 {判断new的可行性}

if not ((X >

 0)and ( X <

4 )and(Y>

 0)and(Y< 4 ))thenbeginok:

=false;

exit end;

 OK:

=true;

new.State:

=n.State;

 {new=Expand(n,d)}

 new.State[X,Y]:

=0;

 new.State[n.x0,n.y0]:

=n.State[X,Y];

 new.X0:

=X;

new.Y0:

=Y;

 end;

procedureAdd(new:

tList);

    {插入节点new}

 begin

  ifnot_Appear(new)then Begin   {如果new没有在List出现}

  Inc(open);

         {new加入open表}

 List[open] :

=new;

 end;

end;

procedureExpand(Index:

integer;

varn:

 tList);

{扩展n的子节点}

vari :

integer;

 new:

tList;

OK:

boolean;

 Begin

 ifSame(n.State, Target) thenbegin    {如果找到解}

 Found:

= true;

 Best:

=n.Dep;

  Answer:

=Index;

  Exit;

end;

  Fori:

=1 to4dobegin         {依次使用4条规则}

  Move(n,i,OK,new);

 ifnotok thencontinue;

new.Father:

=Index;

 new.Dep :

=n.dep+ 1;

Add(new);

 end;

 

procedure GetOutInfo;

       {输出}

procedureOutlook(Index:

integer);

      {递归输出每一个解}

 var i,j:

 integer;

  begin

 ifIndex=0thenexit;

 Outlook(List[Index].Father);

 withList[Index]do      

 fori:

=1to3dobegin

  forj:

=1to 3dowrite(State[i,j],'

'

  writeln;

  end;

  writeln;

  end;

 begin

 Writeln('

Total =',Best);

Outlook(Answer);

  end;

procedureMain;

           {搜索主过程}

 begin

Repeat

Inc(Closed);

Expand(Closed,List[Closed]);

  {扩展Closed}

  Until(Closed>=open)orFound;

ifFound thenGetOutInfo     {存在解}

    else Writeln('noanswer'

     {无解}

Begin

Assign(Input,'

input.txt'

ReSet(Input);

 Assign(Output,'

Output.txt'

ReWrite(Output);

GetInfo;

Initialize;

Main;

  Close(Input);

Close(Output);

End.

五、实验结果

六、实验总结

通过实验问题的求解过程就是搜索的过程,采用适合的搜索算法是关键的,因为对求解过程的效率有很大的影响,包括各种规则、过程和算法等推理技术。

八数码问题中,将牌的移动来描述规则,是一种相对较简单的方法。

用广度优先算法实现八数码问题,其实是一种比较费劲的方式;

然而深度优先将是一个很好的方法,利用深度优先不但减少了程序实现的时间,是一种不错的方式。

但最好的方式是启发式搜索方式实现,在很大程度上相对于前两种方式是一种非常好的实现方式,不但节省了时间,也节省了空间。

  通过这次试验使我对搜索算法有了一定的了解,并对实现这个问题的执行过程有了更一步的认识。

也通过它解决了八数码问题,但在实际的过程中还存在很多问题,也看了一些辅助书籍,以后还要加强学习,加强理论与实际的练习。

总之,这次试验使我受益匪浅。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 表格类模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1