完整版启发式搜索算法Word格式文档下载.docx
《完整版启发式搜索算法Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《完整版启发式搜索算法Word格式文档下载.docx(15页珍藏版)》请在冰豆网上搜索。
![完整版启发式搜索算法Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2022-11/29/ba8304c7-5386-400d-8172-c8fe0eb714b1/ba8304c7-5386-400d-8172-c8fe0eb714b11.gif)
//以上为C++源文件
usingnamespacestd;
staticintspace=0;
inttarget[9];
classEightNum//定义一个EightNum类
{
public:
intnum[9];
intf;
//初始状态与目标状态相比,棋子错放个数
intdeap;
//深度
intevalfun;
//状态的估价值
EightNum*parent;
//以下为类内成员函数的声明
EightNum(intnnum[9]);
intget_evalfun();
intget_deapfun();
voideval_func(intid);
intCanspread(intn);
voidSpreadchild(intn);
voidgetnum(intnum1[9]);
voidsetnum(intnum1[9]);
voidshow(void);
intoperator==(EightNum&
NewEightN);
intoperator==(intnum2[9]);
intShownum();
};
//-----------------------以下为EightNum类成员函数定义-----------------//
classStack
private:
EightNum*eightnum;
public:
Stack*next;
EightNum*Minf();
EightNum*Belong(EightNum*suc);
voidPutinto(EightNum*suc);
EightNum:
:
EightNum(intnnum[9]){//此函数功能为:
初始化num[];
for(inti=0;
i<
9;
i++)
num[i]=nnum[i];
f=0;
deap=0;
parent=NULL;
}
intEightNum:
get_evalfun(){
returnevalfun;
get_deapfun(){
returndeap;
voidEightNum:
eval_func(intid){//此函数为估价函数
inti,qifa;
qifa=0;
switch(id){
case1:
for(i=0;
i++){
if(num[i]!
=target[i])
qifa++;
}
break;
case2:
intj,h1,h2;
for(j=0;
j<
j++){
if(num[j]==i)h1=j;
if(target[j]==i)h2=j;
}
qifa+=(int)(fabs((double)(h1/3-h2/3))+fabs((double)(h1%3-h2%3)));
case3:
qifa=3*qifa;
default:
break;
f=qifa;
if(this->
parent==NULL)deap=0;
elsedeap=this->
parent->
deap+1;
evalfun=deap+f;
Canspread(intn)
{//判断空格"
0"
可否移动
inti,flag=0;
for(i=0;
i<
9;
if(this->
num[i]==0)break;
switch(n)
{
case1:
if(i/3!
=0)flag=1;
case2:
=2)flag=1;
case3:
if(i%3!
case4:
default:
returnflag;
Spreadchild(intn)
{//扩展child节点的子节点
inti,loc,qifa;
this->
num[i]=this->
num[i];
if(n==0)
loc=i%3+(i/3-1)*3;
elseif(n==1)
loc=i%3+(i/3+1)*3;
elseif(n==2)
loc=i%3-1+(i/3)*3;
else
loc=i%3+1+(i/3)*3;
qifa=this->
num[loc];
this->
num[i]=qifa;
num[loc]=0;
getnum(intnum1[9]){
num1[i]=num[i];
setnum(intnum1[9]){
num[i]=num1[i];
show(){//输出函数
cout<
<
num[i]<
"
"
;
if((i+1)%3==0)
\n"
}
cout<
--------------------"
Shownum()
if(this==NULL)return0;
intn=this->
Shownum();
show();
cout<
endl;
returnn+1;
operator==(EightNum&
NewEightN){
intcompere=1;
if(num[i]!
=NewEightN.num[i]){
compere=0;
if(compere==0)return0;
elsereturn1;
//-----------------------以下为分函数的定义---------------------//
//判断是否有解的函数
intsolve(intnum[9],inttarget[9]){
inti,j;
intnum_con=0,tar_con=0;
for(i=0;
for(j=0;
i;
if(num[j]<
num[i]&
&
num[j]!
=0)
num_con++;
if(target[j]<
target[i]&
target[j]!
tar_con++;
num_con=num_con%2;
tar_con=tar_con%2;
if((num_con==0&
tar_con==0)||(num_con==1&
tar_con==1))
return1;
else
return0;
EightNum*Stack:
Minf()
Stack*qifa=this->
next;
Stack*min=this->
Stack*minp=this;
EightNum*minx;
while(qifa->
next!
=NULL)
if((qifa->
next->
eightnum->
get_evalfun())<
(min->
get_evalfun()))
{
min=qifa->
minp=qifa;
qifa=qifa->
minx=min->
eightnum;
qifa=minp->
minp->
next=minp->
free(qifa);
returnminx;
//判断节点是否属于OPEN表或CLOSED表
Belong(EightNum*suc)
Stack*qifa=this->
next;
if(qifa==NULL)returnNULL;
while(qifa!
if(suc==qifa->
eightnum)returnqifa->
returnNULL;
//把节点存入OPEN或CLOSED表中
voidStack:
Putinto(EightNum*suc)
Stack*qifa;
qifa=(Stack*)malloc(sizeof(Stack));
qifa->
eightnum=suc;
next=this->
next=qifa;
intBelongProgram(EightNum*suc,Stack*Open,Stack*Closed,EightNumgoal,intm)
EightNum*qifa=NULL;
intflag=0;
if((Open->
Belong(suc)!
=NULL)||(Closed->
=NULL))
if(Open->
=NULL)qifa=Open->
Belong(suc);
elseqifa=Closed->
flag=1;
Open->
Putinto(suc);
suc->
eval_func(m);
returnflag;
//扩展后继节点总函数
voidSpread(EightNum*suc,Stack*Open,Stack*Closed,EightNumgoal,intm)
inti;
EightNum*child;
i<
4;
i++)
if(suc->
Canspread(i+1))
space++;
child=(EightNum*)malloc(sizeof(EightNum));
child->
parent=suc;
Spreadchild(i);
if(BelongProgram(child,Open,Closed,goal,m))//判断子节点是否属于OPEN或CLOSED表
free(child);
//执行函数
EightNum*Process(EightNum*org,EightNumgoal,Stack*Open,Stack*Closed,intm)
while
(1)
{
next==NULL)returnNULL;
EightNum*minf=Open->
Minf();
Closed->
Putinto(minf);
if((*minf)==goal)returnminf;
Spread(minf,Open,Closed,goal,m);
}
//------------------------A*算法搜索函数----------------------//
voidA(intid,EightNumstart,EightNumTarget)
EightNum*result;
space=0;
floattime;
Stack*Open=(Stack*)malloc(sizeof(Stack));
Open->
next=NULL;
Stack*Closed=(Stack*)malloc(sizeof(Stack));
Closed->
clock_tstartt,finisht;
startt=clock();
//开始时间
start.eval_func(id);
Putinto(&
start);
result=Process(&
start,Target,Open,Closed,id);
//进行剩余的操作
\n搜索过程:
result->
Shownum()<
finisht=clock();
time=(float)(finisht-startt);
endl<
id<
算法处理结果:
所耗时间:
time;
ms,"
所耗空间:
space;
块,"
//-----------------------------主函数-----------------------------//
intmain(void)//主函数
intflag;
intnum[9];
interror;
do{
error=0;
请输入八数码问题的初始状态(0代表空格,“棋子”间用空格隔开):
flag=0;
cin>
>
j++)
if(num[j]==num[i])
flag=1;
if(num[i]<
0||num[i]>
8||flag==1){
error++;
if(error!
输入数据错误!
请重新输入!
}while(error!
=0);
//输入八数码问题的初始状态(0代表空格,“棋子”间用空格隔开);
interror1;
error1=0;
请输入新的目标状态(用0代表空格,“棋子”间用空格隔开):
target[i];
if(target[j]==target[i])
if(target[i]<
0||target[i]>
9||flag==1){
error1++;
if(error1!
}while(error1!
//输入八数码问题的目标状态(用0代表空格,中间用空格隔开);
EightNumstart(num),Target(target);
intm=solve(num,target);
//判断初始状态到目标状态是否有解,有解返回1,误解返回0;
if(m==0){
此状态无解!
intid=0;
while(id!
=3){
1.错放的棋子个数为;
\n2.每个棋子与目标位置之间的距离总和为;
3.结束,退出程序!
\n请选择功能,分别输入“1”“2”“3”进行选择:
id;
switch(id){
{
错放的棋子个数结果为:
\n(以下逐一展示搜索过程:
)"
A(1,start,Target);
break;
每个棋子与其目标位置之间的距离总和为:
A(2,start,Target);
啊啊….程序结束!
!
实验截图
实验中遇到的问题
1:
开始程序只能运行一种方式即按照错位个数搜索,后经过查找相关资料,修改后可程序可进行选择,两种方法结合在一起根据选择运行。
实验总结
通过本次实验让我对八数码问题有了进一步的了解,也对一般图搜索和启发式搜索问题的解决有了更深的理解,启发式函数是通过考虑搜索算法的可采纳性,根据定义的评价函数选择最佳路径的一种方法,根据不同的函数可能得到不同的搜索路径,通过这次实验让我对这类游戏行的程序更加有兴趣,也让我的编程更加熟练和编程的思维更清晰了点,从而对学习编程更加有兴趣了。