本文对八数码问题 启发式搜索 (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 ;
}

c++ 启发式搜索解决八数码问题的更多相关文章

  1. A*算法解决八数码问题 Java语言实现

    0X00 定义 首先要明确一下什么是A*算法和八数码问题? A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法也是一种启发性的算法,也是解决许多搜索问题的有效算法.算法中的距离估 ...

  2. 【算法】BFS+哈希解决八数码问题

    15拼图已经有超过100年; 即使你不叫这个名字知道的话,你已经看到了.它被构造成具有15滑动砖,每一个从1到15上,并且所有包装成4乘4帧与一个瓦块丢失.让我们把丢失的瓷砖“X”; 拼图的目的是安排 ...

  3. 关于八数码问题中的状态判重的三种解决方法(编码、hash、&lt;set&gt;)

    八数码问题搜索有非常多高效方法:如A*算法.双向广搜等 但在搜索过程中都会遇到同一个问题.那就是判重操作(假设反复就剪枝),怎样高效的判重是8数码问题中效率的关键 以下关于几种判重方法进行比較:编码. ...

  4. HDU 1043 Eight 八数码问题 A*算法(经典问题)

    HDU 1043 Eight 八数码问题(经典问题) 题意 经典问题,就不再进行解释了. 这里主要是给你一个状态,然后要你求其到达\(1,2,3,4,5,6,7,8,x\)的转移路径. 解题思路 这里 ...

  5. A*算法 -- 八数码问题和传教士过河问题的代码实现

    前段时间人工智能的课介绍到A*算法,于是便去了解了一下,然后试着用这个算法去解决经典的八数码问题,一开始写用了挺久时间的,后来试着把算法的框架抽离出来,编写成一个通用的算法模板,这样子如果以后需要用到 ...

  6. ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)

    八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个 ...

  7. 双向广搜+hash+康托展开 codevs 1225 八数码难题

    codevs 1225 八数码难题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description Yours和zero在研究A*启 ...

  8. Codevs 1225 八数码难题

    1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的 ...

  9. A*八数码

    帮同学写的八数码,启发式搜索 创建两个表open,close,分别用的stl中的优先队列priority_queue和map,好久没写过代码了,bug调了半天 #include <iostrea ...

随机推荐

  1. golang超级mapper包 - coven

    coven介绍 你可以把它理解成.NET 的 AutoMapper,java的modelmapper 一个快速的转换器去,支持结构到结构,切片到切片和映射到映射非反射转换,类型与嵌套指针支持. 不支持 ...

  2. HTML节点操作

    HTML节点操作 HTML节点的基本操作,添加节点,替换节点,删除节点,绑定事件,访问子节点,访问父节点,访问兄弟节点. 文档对象模型Document Object Model,简称DOM,是W3C组 ...

  3. Python第五章-内置数据结构02-列表

    Python 内置的数据结构 二.列表(list) 想一想: 前面学习的字符串可以用来存储一串信息,那么想一想,怎样存储咱们班所有同学的名字呢? 定义100个变量,每个变量存放一个学生的姓名可行吗?有 ...

  4. MySQL笔记(9)-- 各种锁及实现

    一.背景 MySQL有两种类型的锁:lock(锁)和latch(闩锁): 类型 lock latch 对象 事务 线程 保护 数据库内容 内存数据结构 持续时间 整个事务 临界资源 模式 行锁.表锁. ...

  5. Redis系列(一):小试牛刀

    引言 随着互联网的高速发展,传统的关系数据库(如MySQL.Microsoft SQL Server等)已不能满足日益增长的业务需求,如商品秒杀.抢购等及时性非常强的功能,随着应用高并发的访问,会造成 ...

  6. 使用PyTorch建立图像分类模型

    概述 在PyTorch中构建自己的卷积神经网络(CNN)的实践教程 我们将研究一个图像分类问题--CNN的一个经典和广泛使用的应用 我们将以实用的格式介绍深度学习概念 介绍 我被神经网络的力量和能力所 ...

  7. Python python 函数参数:关键字参数

    # 关键字参数 '''关键字参数代表传入任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict ''' def student(name,sex,**keywords): print(' ...

  8. thinkphp5.1中使用链式操作的坑

    1.在进行tp5->tp5.1的时候,没有想太多,直接使用之前的代码:结果在该操作中,多次调用该get方法,tp5.1的链式操作一直保持了之前的搜索条件,截图如下:(具体的代码没有展示) 2.然 ...

  9. GitHub 热点速览 Vol.14:周获 2k+ Vim 掀起三维编程风

    作者:HelloGitHub-小鱼干 摘要(用于 公众号/博客园等地方)寓教于乐,应该是上周 Trending 的主题了,无论是被多人转发推荐的三维 Vim 项目 Vim³ 或者是流体运动的 WebG ...

  10. Let‘s play computer game(最短路 + dfs找出所有确定长度的最短路)

    Let's play computer game Description xxxxxxxxx在疫情期间迷上了一款游戏,这个游戏一共有nnn个地点(编号为1--n1--n1--n),他每次从一个地点移动 ...