八数码问题C语言A星算法详细实验报告含代码Word文档下载推荐.docx

上传人:b****8 文档编号:22680105 上传时间:2023-02-05 格式:DOCX 页数:14 大小:232.47KB
下载 相关 举报
八数码问题C语言A星算法详细实验报告含代码Word文档下载推荐.docx_第1页
第1页 / 共14页
八数码问题C语言A星算法详细实验报告含代码Word文档下载推荐.docx_第2页
第2页 / 共14页
八数码问题C语言A星算法详细实验报告含代码Word文档下载推荐.docx_第3页
第3页 / 共14页
八数码问题C语言A星算法详细实验报告含代码Word文档下载推荐.docx_第4页
第4页 / 共14页
八数码问题C语言A星算法详细实验报告含代码Word文档下载推荐.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

八数码问题C语言A星算法详细实验报告含代码Word文档下载推荐.docx

《八数码问题C语言A星算法详细实验报告含代码Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《八数码问题C语言A星算法详细实验报告含代码Word文档下载推荐.docx(14页珍藏版)》请在冰豆网上搜索。

八数码问题C语言A星算法详细实验报告含代码Word文档下载推荐.docx

(n)是n到目标的最短路经的启发值。

由于这个f'

(n)其实是无法预先知道的,所以实际上使用的是下面的估价函数:

f(n)=g(n)+h(n)

其中g(n)是从初始结点到节点n的实际代价,h(n)是从结点n到目标结点的最佳路径的估计代价。

在这里主要是h(n)体现了搜索的启发信息,因为g(n)是已知的。

用f(n)作为f'

(n)的近似,也就是用g(n)代替g'

(n),h(n)代替h'

(n)。

这样必须满足两个条件:

(1)g(n)>

=g'

(n)(大多数情况下都是满足的,可以不用考虑),且f必须保持单调递增。

(2)h必须小于等于实际的从当前节点到达目标节点的最小耗费h(n)<

=h'

第二点特别的重要。

可以证明应用这样的估价函数是可以找到最短路径的。

3.A*算法的步骤

A*算法基本上与广度优先算法相同,但是在扩展出一个结点后,要计算它的估价函数,并根据估价函数对待扩展的结点排序,从而保证每次扩展的结点都是估价函数最小的结点。

A*算法的步骤如下:

1)建立一个队列,计算初始结点的估价函数f,并将初始结点入队,设置队列头和尾指针。

2)取出队列头(队列头指针所指)的结点,如果该结点是目标结点,则输出路径,程序结束。

否则对结点进行扩展。

3)检查扩展出的新结点是否与队列中的结点重复,若与不能再扩展的结点重复(位于队列头指针之前),则将它抛弃;

若新结点与待扩展的结点重复(位于队列头指针之后),则比较两个结点的估价函数中g的大小,保留较小g值的结点。

跳至第五步。

4)如果扩展出的新结点与队列中的结点不重复,则按照它的估价函数f大小将它插入队列中的头结点后待扩展结点的适当位置,使它们按从小到大的顺序排列,最后更新队列尾指针。

5)如果队列头的结点还可以扩展,直接返回第二步。

否则将队列头指针指向下一结点,再返回第二步。

四、程序框图

五、实验结果及分析

输入初始状态:

283目标状态:

123

164804

705765

运行结果屏幕打印

OPEN表与CLOSE表:

OPEN

CLOSE

1234

23456

01

23467

015

234689

0157

2348910

01576

2348111213

015769

234812131415

01576911

348121314151617

015769112

481213141516171819

0157691123

481213141516171920

015769112318

8121314151617192122

0157691123184

12131415161719212223

01576911231848

1213141516171921222425

0157691123184823

1213141516171921222426

015769112318482324

发现26为目标节点

搜索树:

 

六、结论

对于八数码问题,BFS算法最慢,A*算法较快。

八数码问题的一个状态实际上是0~9的一个排列,对于任意给定的初始状态和目标,不一定有解,也就是说从初始状态不一定能到达目标状态。

因为排列有奇排列和偶排列两类,从奇排列不能转化成偶排列。

如果一个数字0~8的随机排列871526340,用F(X)表示数字X前面比它小的数的个数,全部数字的F(X)之和为Y=∑(F(X)),如果Y为奇数则称原数字的排列是奇排列,如果Y为偶数则称原数字的排列是偶排列。

因此,可以在运行程序前检查初始状态和目标状态的排序的奇偶行是否相同,相同则问题可解,应当能搜索到路径。

否则无解。

七、源程序及注释

#include<

iostream>

ctime>

vector>

usingnamespacestd;

constintROW=3;

constintCOL=3;

constintMAXDISTANCE=10000;

constintMAXNUM=10000;

intabs(inta)

{

if(a>

0)returna;

elsereturn-a;

}

typedefstruct_Node{

intdigit[ROW][COL];

intdist;

//距离

intdep;

//深度

intindex;

//索引值

}Node;

Nodesrc,dest;

vector<

Node>

node_v;

//储存节点

boolisEmptyOfOPEN(){//判断Open表是否空

for(inti=0;

i<

node_v.size();

i++){

if(node_v[i].dist!

=MAXNUM)

returnfalse;

returntrue;

boolisEqual(intindex,intdigit[][COL]){//判断节点是否与索引值指向的节点相同

ROW;

i++)

for(intj=0;

j<

COL;

j++){

if(node_v[index].digit[i][j]!

=digit[i][j])

}

ostream&

operator<

<

(ostream&

os,Node&

node){

j++)

os<

node.digit[i][j]<

'

;

endl;

returnos;

voidPrintSteps(intindex,vector<

&

rstep_v){//输出步骤

rstep_v.push_back(node_v[index]);

index=node_v[index].index;

while(index!

=0){

rstep_v.push_back(node_v[index]);

index=node_v[index].index;

for(inti=rstep_v.size()-1;

i>

=0;

i--)

cout<

"

Step"

<

rstep_v.size()-i

endl<

rstep_v[i]<

voidSwap(int&

a,int&

b){//交换

intt;

t=a;

a=b;

b=t;

voidAssign(Node&

node,intindex){//获取节点

node.digit[i][j]=node_v[index].digit[i][j];

intGetMinNode(){//获取启发值最小的节点

intdist=MAXNUM;

intloc;

//thelocationofminimizenode

if(node_v[i].dist==MAXNUM)

continue;

elseif((node_v[i].dist+node_v[i].dep)<

dist){

loc=i;

dist=node_v[i].dist+node_v[i].dep;

returnloc;

boolisExpandable(Node&

node){//判断是否可扩展

if(isEqual(i,node.digit))

intDistance(Node&

node,intdigit[][COL]){//计算距离

intdistance=0;

boolflag=false;

for(inti=0;

i++)

j++)

for(intk=0;

k<

k++){

for(intl=0;

l<

l++){

if(node.digit[i][j]==digit[k][l]){

distance+=abs(i-k)+abs(j-l);

flag=true;

break;

else

flag=false;

if(flag)

returndistance;

intMinDistance(inta,intb){//二者取小

return(a<

b?

a:

b);

voidProcessNode(intindex){//展开节点

intx,y;

boolflag;

if(node_v[index].digit[i][j]==0){

x=i;

y=j;

elseflag=false;

if(flag)

Nodenode_up;

//上移操作

Assign(node_up,index);

intdist_up=MAXDISTANCE;

if(x>

0){

Swap(node_up.digit[x][y],node_up.digit[x-1][y]);

if(isExpandable(node_up)){

dist_up=Distance(node_up,dest.digit);

node_up.index=index;

node_up.dist=dist_up;

node_up.dep=node_v[index].dep+1;

node_v.push_back(node_up);

Nodenode_down;

//下移操作

Assign(node_down,index);

intdist_down=MAXDISTANCE;

if(x<

2){

Swap(node_down.digit[x][y],node_down.digit[x+1][y]);

if(isExpandable(node_down)){

dist_down=Distance(node_down,dest.digit);

node_down.index=index;

node_down.dist=dist_down;

node_down.dep=node_v[index].dep+1;

node_v.push_back(node_down);

Nodenode_left;

//左移操作

Assign(node_left,index);

intdist_left=MAXDISTANCE;

if(y>

Swap(node_left.digit[x][y],node_left.digit[x][y-1]);

if(isExpandable(node_left)){

dist_left=Distance(node_left,dest.digit);

node_left.index=index;

node_left.dist=dist_left;

node_left.dep=node_v[index].dep+1;

node_v.push_back(node_left);

Nodenode_right;

//右移操作

Assign(node_right,index);

intdist_right=MAXDISTANCE;

if(y<

Swap(node_right.digit[x][y],node_right.digit[x][y+1]);

if(isExpandable(node_right)){

dist_right=Distance(node_right,dest.digit);

node_right.index=index;

node_right.dist=dist_right;

node_right.dep=node_v[index].dep+1;

node_v.push_back(node_right);

node_v[index].dist=MAXNUM;

intmain(){

intnumber;

cout<

输入初始状态:

"

cin>

>

number;

src.digit[i][j]=number;

src.index=0;

src.dep=1;

输入目标状态"

for(intm=0;

m<

m++)

for(intn=0;

n<

n++){

dest.digit[m][n]=number;

node_v.push_back(src);

while

(1){

if(isEmptyOfOPEN()){

找不到解!

return-1;

else{

intloc;

//thelocationoftheminimizenode

loc=GetMinNode();

if(isEqual(loc,dest.digit)){

vector<

rstep_v;

初始状态:

src<

PrintSteps(loc,rstep_v);

成功!

ProcessNode(loc);

return0;

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

当前位置:首页 > 解决方案 > 学习计划

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

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