本文对八数码问题 启发式搜索 (C++)做了一点点修改

 //fn=gn+hn

 #include<iostream>
#include<queue>
#include<stack> using namespace std; #define num 9 struct node
{
int state[];//当前状态
struct node* parent;//父节点
int value;//值
int depth;//在树中的深度
friend bool operator < (node A, node B) //按照value值小的方案构造优先级队列
{
return A.value > B.value;
}
}; priority_queue<node> openTable; //open表
queue<node> closeTable; //close表
stack<node> Path; //最终路径 void init(node& s,node& g)
{//初始化
s.parent=NULL;
s.depth=;
s.value=;
g.parent=NULL;
g.depth=;
g.value=; cout<<"please input the init status"<<endl;
for(int i=;i<num;i++)
{
cin>>s.state[i];
} cout<<"please input the target status"<<endl;
for(int i=;i<num;i++)
{
cin>>g.state[i];
} } bool isreachable(node s,node g)
{//判断目标是否可达。若2个状态的逆序奇偶性相同则可达,不相同则不可达。
int count1=;
int count2=;
for(int i=;i<=num-;i++)
{
for(int j=i+;j<num;j++)
{
if(s.state[i]>s.state[j]&&s.state[i]*s.state[j]!=)
{
count1++;
}
}
} for(int i=;i<=num-;i++)
{
for(int j=i+;j<num;j++)
{
if(g.state[i]>g.state[j]&&g.state[i]*g.state[j]!=)
{
count2++;
}
}
} if(count1%!=count2%)
{
return false;
}
return true; } int value(node a,node g)
{//hn
int count=;
for(int i=;i<num;i++)
{
if(a.state[i]==)
{
continue;
}
else if(a.state[i]!=g.state[i])
{
for(int j=;j<num;j++)
{
if(a.state[i]==g.state[j])
{
count+=abs(i/-j/)+abs(i%-j%);
}
}
}
}
return count+a.depth;
} bool isequal(node a,node g)
{//当前节点是否是目标
for(int i=;i<num;i++)
{
if(a.state[i]!=g.state[i])
{
return false;
}
}
return true;
} bool createNode(node& a,node g)
{//产生新节点,加入open表
bool flag=true;
/* 计算原状态下,空格所在的行列数,从而判断空格可以往哪个方向移动 */
int blank;//定义空格下标
for(blank=;blank<num;blank++)
{
if(a.state[blank]==)
{
break;
}
}
if(blank==num)return false;
int x=blank/,y=blank%;//获取空格所在行列编号
/*找到S扩展的子节点,加入open表中*/
for(int d=;d<;d++)
{
int newx=x,newy=y;//新空白格坐标
node tempnode;//临时节点,子节点 /*移动空格*/
switch (d)
{
case ://向上
newx--;
if(newx<)continue;
break;
case ://向左
newy--;
if(newy<)continue;
break;
case ://向下
newx++;
if(newx>)continue;
break;
case ://向右
newy++;
if(newy>)continue;
break; default:
break;
} /*交换新旧空白格的内容*/
int newblank=newx*+newy;//新空格下标 if (newx >= && newx < && newy >= && newy < )
{
tempnode=a;
tempnode.state[blank]=tempnode.state[newblank];
tempnode.state[newblank]=;
if(a.parent!=NULL&&(*a.parent).state[newblank]==)
{//如果新节点和爷爷节点一样,舍弃该节点
continue;
} /*把子节点都加入open表中*/
tempnode.parent=&a;
tempnode.value=value(tempnode,g);
tempnode.depth=a.depth+;
openTable.push(tempnode);
}
}
return flag;
} bool findpath(node s,node g)
{//s->g
bool flag=true;
/*find path*/
openTable.push(s);
while(true)
{
closeTable.push(openTable.top());
openTable.pop();
if(!isequal(closeTable.back(),g))
{
flag=createNode(closeTable.back(),g);
}
else
{
break;
} }
/*make path*/
node tempnode;
tempnode=closeTable.back();
while(tempnode.parent!=NULL)
{
Path.push(tempnode);
tempnode=*(tempnode.parent);
}
Path.push(tempnode);
return flag;
} void printpath()
{//print path s -> g
cout<<"move "<<Path.size()-<<" step"<<endl;
while(Path.size()!=)
{
for(int i=;i<num;i++)
{
cout<<Path.top().state[i]<<" ";
if((i+)%==)cout<<endl;
}
Path.pop();
cout<<endl;
}
} int main()
{
node s,g;
init(s,g);
if(!isreachable(s,g))
{
cout<<"cannot reach"<<endl;
system("pause");
return ;
}
else if (!findpath(s,g))
{
cout<<"findpath error"<<endl;
system("pause");
return ;
}
else
{
printpath();
cout<<"done"<<endl;
}
system("pause");
return ;
}

最新文章

  1. Linux驱动学习 —— 在/sys下面创建目录示例
  2. 彻底理解nth-child和nth-of-type的区别。
  3. python 自动发邮件 Errno61 Connection refused
  4. shell脚本(管理守护进程)
  5. Android Studio 调试过程中快捷查看断点处变量值(Ctrl+Shift+I无效)?
  6. IE8,9下的ajax缓存问题
  7. HDU 1329 Hanoi Tower Troubles Again!(乱搞)
  8. 两种利用GCD实现分步获取结果的方式和SDWebImage缓存机制的验证
  9. 从壹开始微服务 [ DDD ] 之十一 ║ 基于源码分析,命令分发的过程(二)
  10. 2018-2019-2 网络对抗技术 20165239 Exp2 后门原理与实践
  11. 戏说春秋_i春秋 writeup
  12. Flask 模型操作
  13. 数据结构_1+AI_1
  14. 学习笔记第六课 VB程序
  15. 编写高质量代码:改善Java程序的151个建议 --[117~128]
  16. 832B Petya and Exam
  17. 【转】MySQL用户管理及SQL语句详解
  18. Egret 项目文件夹配置和基本容器、动画
  19. [POJ 2689] Prime Distance
  20. hdu 3033(好题,分组背包)

热门文章

  1. Linux软件安装之JDK的安装
  2. nmap加载nse脚本在内网渗透中的使用-上
  3. Javascript之盒子拖拽(跟随鼠标、边界限定、轨迹回放)
  4. 搭建Hadoop集群需要注意的问题:
  5. Hive视图如何创建、特点及应用场景
  6. swagger2 接口文档
  7. 在EF中使用SQL执行简单高效的增删查操作
  8. nginx 报 502 bad gateway 分析解决
  9. Pytest系列(5) - 用例执行的几种状态
  10. python:&lt;class &#39;numpy.ndarray&#39;&gt;的学习