用A算法解决八数码问题

合集下载

a算法八数码问题例题

a算法八数码问题例题

a算法八数码问题例题八数码问题是一个经典的搜索问题,其中有一个3×3的格子,其中包含了一些数字(通常是1到8),以及一个空白格。

目标是使用最少的步骤将格子中的数字排列成给定的目标顺序。

每个步骤可以是以下三种操作之一:1. 上下移动(将行中的某个数字上移或下移)2. 左右移动(将列中的某个数字左移或右移)3. 旋转(以中心为中心旋转整个格子)下面是一个使用A算法解决八数码问题的例子:假设初始状态如下:```markdown4 1 2 756 3 8 05 0 3 2 4 167 86 7 5 8 3 4 2 1 0```目标状态如下:```markdown1 2 3 4 5 6 7 8 00 3 6 7 4 5 8 1 27 8 5 6 1 2 3 4 0```下面是使用A算法解决这个问题的步骤:1. 首先,我们需要构建一个优先级队列(例如最小堆),用于存储所有可能的移动。

在这个例子中,每个移动都有一个成本和优先级。

成本是从当前状态到目标状态的最短路径长度,优先级是当前状态到目标状态的H启发式估计。

H启发式估计通常是当前状态和目标状态之间的曼哈顿距离。

2. 从队列中取出优先级最高(即成本最低)的移动。

在这个例子中,初始状态的移动是"上下移动"。

3. 应用这个移动,并更新所有相关状态的成本和优先级。

在这个例子中,我们将第一行向下移动一格。

然后,我们需要重新评估所有可能的状态,并更新优先级队列。

4. 在更新优先级队列后,我们需要检查是否已经达到目标状态。

如果已经达到目标状态,则算法结束。

否则,我们重复步骤2和步骤3,直到达到目标状态。

5. 在这个例子中,我们需要进行多次上下移动、左右移动和旋转,才能将数字排列成目标顺序。

每次应用移动后,都需要重新评估所有可能的状态,并更新优先级队列。

a星算法求解八数码问题python

a星算法求解八数码问题python

a星算法求解八数码问题python一、介绍八数码问题是一种经典的智力游戏,也是人工智能领域中的经典问题之一。

在这个问题中,有一个3×3的棋盘,上面摆着1至8这8个数字和一个空格,初始状态和目标状态都已知。

要求通过移动数字,将初始状态变换成目标状态。

其中空格可以和相邻的数字交换位置。

为了解决这个问题,我们可以使用A*算法。

本文将详细介绍如何用Python实现A*算法来求解八数码问题。

二、A*算法简介A*算法是一种启发式搜索算法,常用于寻找最短路径或最优解等问题。

它基于Dijkstra算法,并加入了启发式函数来加速搜索过程。

在A*算法中,每个节点都有两个估价值:g值和h值。

g值表示从起点到该节点的实际代价,h值表示从该节点到目标节点的估计代价。

启发式函数f(n) = g(n) + h(n) 表示从起点到目标节点的估计总代价。

A*算法采用优先队列来保存待扩展的节点,并按照f(n)值从小到大排序。

每次取出队头元素进行扩展,并将扩展出来的新节点按照f(n)值插入队列中。

当扩展出目标节点时,算法结束。

三、八数码问题的状态表示在八数码问题中,每个状态都可以表示为一个3×3的矩阵。

我们可以用一个一维数组来表示这个矩阵,其中0表示空格。

例如,初始状态可以表示为[2, 8, 3, 1, 6, 4, 7, 0, 5],目标状态可以表示为[1, 2, 3, 8, 0, 4, 7, 6, 5]。

四、A*算法求解八数码问题的步骤1.将初始状态加入优先队列中,并设置g值和h值为0。

2.从队头取出一个节点进行扩展。

如果该节点是目标节点,则搜索结束;否则,将扩展出来的新节点加入优先队列中。

3.对于每个新节点,计算g值和h值,并更新f(n)值。

如果该节点已经在优先队列中,则更新其估价值;否则,将其加入优先队列中。

4.重复第2步至第3步直到搜索结束。

五、Python实现以下是用Python实现A*算法求解八数码问题的代码:```import heapqimport copy# 目标状态goal_state = [1,2,3,8,0,4,7,6,5]# 启发式函数:曼哈顿距离def h(state):distance = 0for i in range(9):if state[i] == 0:continuerow = i // 3col = i % 3goal_row = (state[i]-1) // 3goal_col = (state[i]-1) % 3distance += abs(row - goal_row) + abs(col - goal_col)return distance# A*算法def A_star(start_state):# 初始化优先队列和已访问集合queue = []visited = set()# 将初始状态加入优先队列中,并设置g值和h值为0heapq.heappush(queue, (h(start_state), start_state, 0))while queue:# 取出队头元素进行扩展f, state, g = heapq.heappop(queue)# 如果该节点是目标节点,则搜索结束;否则,将扩展出来的新节点加入优先队列中。

AStar算法解决八数码问题

AStar算法解决八数码问题

江南大学物联网工程学院实验报告课程名称人工智能实验名称A*算法解决8数码问题实验日期2018.3.20班级计科1501 姓名周启航学号1030415127一、实验目的:修改A*算法,使之能解决N*N矩阵八数码问题问题描述:八数码难题:在3×3方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的八张牌,初始状态S0可自己随机设定,使用的操作有:空格上移,空格左移,空格右移,空格下移。

二、算法描述:1.状态描述八数码的任何一种摆法就是一个状态,所有摆法即为状态集S,他们构成了一个状态空间,其大小为9包括8个数码和一个空格,每个数码就是一个分离的独立的子空间,其所在位置为x:i/3,y:i%3.相应的操作算子就是数码的移动即:将空格向上移UP、将空格向下移DOWN、将空格向左移LEFT、将空格向右移RIGHT,经过一些操作算子后达到目标状态。

2.启发函数设计启发函数为现在的状态中各位置与目标状态各位置数码值不同的个数,例如:现在状态:w=123456780,目标状态为:t=123456708,则h(n)=2.3.规则的判断条件把未扩展的状态存入open表,排序后取出优先状态扩展搜索,将扩展后的存入closed表,循环执行直到扩展出目标状态。

4.算法流程图5.核心代码操作算子:int solve() //搜索过程{P cur;P p;while(!open.empty()){cur=open.top(); //open表open.pop();if(cur.s==t) return cur.id; //达到目标状态,返回当前节点的idint x,y;int ops=0;while(cur.s[ops]!='0') ops++;x=ops/N,y=ops%N; //空格所在位置int r=cur.id;if(x>0){ //空格向上移p.s=cur.s;swap(p.s[ops],p.s[ops-3]);if(!mp[p.s]){p.d=cur.d+1,p.w=calw(p.s),p.id=top+1;open.push(p);stack[++top]=p.s;father[top]=r;mp[p.s]=1;}}if(x<N-1){ //空格向下移p.s=cur.s;swap(p.s[ops],p.s[ops+3]);if(!mp[p.s]){p.d=cur.d+1,p.w=calw(p.s),p.id=top+1;open.push(p);stack[++top]=p.s;father[top]=r;mp[p.s]=1;}}if(y>0){ //空格向左移p.s=cur.s;swap(p.s[ops],p.s[ops-1]);if(!mp[p.s]){p.d=cur.d+1,p.w=calw(p.s),p.id=top+1;open.push(p);stack[++top]=p.s;father[top]=r;mp[p.s]=1;}}if(y<N-1){ //空格向右移p.s=cur.s;swap(p.s[ops],p.s[ops+1]);if(!mp[p.s]){p.d=cur.d+1,p.w=calw(p.s),p.id=top+1;open.push(p);stack[++top]=p.s;father[top]=r;mp[p.s]=1;}}}return -1; //搜索失败}int main(){cout<<"请输入棋盘大小N*N\nN:";cin>>N;cout<<"请输入测试的组数:\n";int tt; //测试的组数cin>>tt;for(int k=1;k<=tt;k++){cout<<"Case "<<k<<":\n";int i,j;char a;cout<<"请输入目的状态:\n";cin>>t;p.s="";cout<<"请输入初始状态:\n";for(i=0;i<N;i++){for(j=0;j<N;j++){cin>>a; //输入0~8数码p.s+=a;}}p.d=0,p.w=calw(p.s),p.id=0;father[0]=-1;mp[p.s]=1;stack[0]=p.s;open.push(p); //往open表中加入初始状态节点int id=solve();//调用搜索过程if(id==-1){cout<<"无解!\n";}else{int c=-1;while(id>=0){ //把stack中存的节点按次序放入到record中record[++c]=stack[id];id=father[id];}cout<<"原图:"<<endl;print(c); //输出初始节点cout<<"移动过程: \n\n";for(i=c-1;i>=0;i--){cout<<"Step "<<c-i<<":\n";//输出当前搜索步骤print(i);//输出当前搜索的节点}cout<<"移动结束!\n";mp.clear();while(!open.empty()) open.pop();top=0;cout<<endl;}system("pause\n");return 0;}三、实验结果:四、实验心得:只是做了简单修改,只能解决些简单的问题,过于复杂的还不能实现,不过还是体会到了A*算法的厉害,也见识到了人工智能的神奇,会继续努力学习。

基于启发式搜索算法A星解决八数码问题

基于启发式搜索算法A星解决八数码问题
//定义算法中用到的链表,图,树的节点的结构。 struct Node {
int statue[size][size]; //记录当前节点的状态 struct Node * Tparent; //用来构成搜索树,该树由搜索图的反向指针构成 struct Node * opennext; //用来构成 open 表,该指针指向该节点在 open 表中的下一个 节点 struct Node * closenext; //用来构成 open 表,该指针指向该节点在 close 表中的下一个 节点 struct Node * brothernext; //构成兄弟链表,该指针指向该节点在兄弟链表中的下一个节 点 int f; //记录当前节点的 f 函数值 int g; //记录当前节点的 g 函数的值 int h; //记录当前节点的 h 函数的值 };
5
get_bestroute (bestNode); return; }
2.2.7 生成 bestNode 所指节点的后继节点
定义一个后继节点链表,表头为 head_b,将 bestNode 所指节点的不是前驱节点的后继 节点,链接到后继及诶单链表中。getchild 函数可以实现这个功能。
//产生 bestNode 的一切后继节点。。 head head_b; //定义 bestNode 的后继节点表 head_b.next=NULL; getchild (&head_b,bestNode); //产生 bestNode 的子节点,将不是 bestNode 的父节点的
while (head_b.next!=NULL) { Node *tmp=getbrother (&head_b); //从后继节点表中取出一个节点记为 tmp,并从

用A算法解决八数码问题

用A算法解决八数码问题

用A*算法解决八数码问题一、 题目:八数码问题也称为九宫问题。

在3×3的棋盘,有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。

棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。

要解决的问题是:任意给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。

二、 问题的搜索形式描述状态:状态描述了8个棋子和空位在棋盘的9个方格上的分布。

初始状态:任何状态都可以被指定为初始状态。

操作符:用来产生4个行动(上下左右移动)。

目标测试:用来检测状态是否能匹配上图的目标布局。

路径费用函数:每一步的费用为1,因此整个路径的费用是路径中的步数。

现在任意给定一个初始状态,要求找到一种搜索策略,用尽可能少的步数得到上图的目标状态算法介绍三、 解决方案介绍1.A*算法的一般介绍A*(A-Star)算法是一种静态路网中求解最短路最有效的方法。

对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即()()()()()()**f g n sqrt dx nx dx nx dy ny dy ny =+--+--;这样估价函数f 在g 值一定的情况下,会或多或少的受估价值h 的制约,节点距目标点近,h 值小,f 值相对就小,能保证最短路的搜索向终点的方向进行。

明显优于盲目搜索策略。

A star算法在静态路网中的应用2.算法伪代码创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。

算起点的估价值,将起点放入OPEN表。

while(OPEN!=NULL){从OPEN表中取估价值f最小的节点n;if(n节点==目标节点){break;}for(当前节点n 的每个子节点X){算X的估价值;if(X in OPEN){if( X的估价值小于OPEN表的估价值 ){把n设置为X的父亲;更新OPEN表中的估价值; //取最小路径的估价值}}if(X inCLOSE){if( X的估价值小于CLOSE表的估价值 ){把n设置为X的父亲;更新CLOSE表中的估价值;把X节点放入OPEN //取最小路径的估价值}}if(X not inboth){把n设置为X的父亲;求X的估价值;并将X插入OPEN表中; //还没有排序}}//end for将n节点插入CLOSE表中;按照估价值将OPEN表中的节点排序; //实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。

基于A星算法的8数码问题求解方案设计(1)

基于A星算法的8数码问题求解方案设计(1)

基于A星算法的8数码问题求解⽅案设计(1)⼀、问题描述8数码问题⼜称9宫问题,与游戏“华容道”类似。

意在给定的33棋格的8个格⼦内分别放⼀个符号,符号之间互不相同,余下的⼀格为空格。

并且通常把8个符号在棋格上的排列顺序称作8数码的状态。

开始时,规则给定⼀个初始状态和⼀个⽬标状态,并要求被试者对棋格内的符号经过若⼲次移动由初始状态达到⽬标状态,这个过程中只有空格附近的符号可以朝空格的⽅向移动,且每次只能移动⼀个符号。

为⽅便编程和表⽰,本⽂中8个格⼦内的符号分别取1—8的8个数字表⽰,空格⽤0表⽰。

并给定8数码的初始状态和⽬标状态分别如图1、2所⽰。

图1 初始状态图2 ⽬标状态则要求以图1为初始状态,通过交换0和0的上、下、左、右四个⽅位的数字(每次只能和其中⼀个交换),达到图2所⽰⽬标状态。

⼆、实验⽬的熟悉和掌握启发式搜索的定义、估价函数和算法过程,并利⽤A*算法求解N数码难题,理解求解流程和搜索顺序。

三、实验任务1)实现类似于如图所⽰N数码难题演⽰程序。

2)⽤你所熟悉的程序语⾔实现,可以B/S实现,也可以C/S实现四、算法设计根据任务要求,本⽂采⽤A*搜索算法。

但要在计算机上通过编程解决该问题,还应当解决该问题在计算机上表⽰的⽅式,并设计合适的启发函数,以提⾼搜索效率。

①状态的表⽰在A*算法中,需要⽤到open表和closed表,特别是在open表中,待扩展节点间有很严格的扩展顺序。

因此在表⽰当前状态的变量中,必须要有能指向下⼀个扩展节点的指针,以完成对open表中元素的索引。

从这⼀点上看,open表中的元素相互间即构成了⼀个线性表,因此初步选定使⽤结构体表⽰问题的状态。

如图3所⽰,表⽰问题的结构体包括表⽰当前节点状态的DATA和指向open 表中下⼀个待扩展节点的指针NEXT。

图3 结构体现在进⼀步考虑DATA中包括的内容:如图1、2所⽰,8数码问题的提出是以⼀个33数表表⽰的,因此本⽂中采⽤⼀个33的⼆维数组s[3][3]表⽰当前状态的具体信息。

A-star-算法-八数码问题-C++-报告+代码+详细注释1

A-star-算法-八数码问题-C++-报告+代码+详细注释1

二、程序运行测试A*算法求解八数码问题一、详细设计说明1.评价函数以当前状态下各将牌到目标位置的距离之和作为节点的评价标准。

距离的定义为: “某将牌行下标与目标位置行下标之差的绝对值 + 列下标与目标位置列下标之差的绝对值”。

距离越小, 该节点的效果越好。

某个状态所有将牌到目标位置的距离之和用“h值”表示。

2.主要函数2.1countH(state & st);countH函数功能是计算st状态的h值。

2.2计算过程中将会用到rightPos数组, 数组里记录的是目标状态下, 0~9每个将牌在九宫格里的位置(位置 = 行下标 * 3 + 列下标)。

2.3f(state * p);f()=h()+level2.4look_up_dup(vector<state*> & vec, state * p);2.5在open表或close表中, 是否存在指定状态p, 当找到与p完全相等的节点时, 退出函数。

2.6search(state & start);在open表不为空时, 按f值由小到大对open表中元素进行排序。

调用findZero()函数找到0值元素的位置。

空格可以向上下左右四个方向移动, 前提是移动后不能越过九宫格的边界线。

确定某方向可走后, 空格移动一步, 生成状态p’。

2.7此时, 检查open表中是否已有p’, 若有, 更新p’数据;检查close表中是否已有p’, 若有, 将p’从close表中删除, 添加到open表中。

2.8重复的执行这个过程, 直到某状态的h值为零。

2.9dump_solution(state * q);在终端输出解路径。

// A*算法八数码问题#include"stdafx.h"#include<iostream>#include<vector>#include<time.h>#include<algorithm>using namespace std;const int GRID = 3; //Grid表示表格的行数(列数), 这是3*3的九宫格int rightPos[9] = { 4, 0, 1, 2, 5, 8, 7, 6, 3 };//目标状态时, 若p[i][j]=OMG,那么3*i+j = rightPos[OMG]struct state{int panel[GRID][GRID];int level; //记录深度int h;state * parent;state(int level) :level(level){}bool operator == (state & q){//判断两个状态是否完全相等(对应位置元素相等), 完全相等返回true,否则返回falsefor (int i = 0; i<GRID; i++){for (int j = 0; j<GRID; j++){if (panel[i][j] != q.panel[i][j])return false;}}return true;}state & operator = (state & p){ //以状态p为当前状态赋值, 对应位置元素相同for (int i = 0; i<GRID; i++){for (int j = 0; j<GRID; j++){panel[i][j] = p.panel[i][j];}}return *this;}};void dump_panel(state * p){ //将八数码按3*3矩阵形式输出for (int i = 0; i<GRID; i++){for (int j = 0; j<GRID; j++)cout << p->panel[i][j] << " ";cout << endl;}}int countH(state & st){ //给定状态st, 计算它的h值。

用A算法解八数码问题

用A算法解八数码问题

用A*算法解八数码问题1.启发式搜索广度优先搜索和双向广度优先搜索都属于盲目搜索,这在状态空间不大的情况下是很合适的算法,可是当状态空间十分庞大时,它们的效率实在太低,往往都是在搜索了大量无关的状态结点后才碰到解答,甚至更本不能碰到解答。

搜索是一种试探性的查寻过程,为了减少搜索的盲目性引,增加试探的准确性,就要采用启发式搜索了。

所谓启发式搜索就是在搜索中要对每一个搜索的位置进行评估,从中选择最好、可能容易到达目标的位置,再从这个位置向前进行搜索,这样就可以在搜索中省略大量无关的结点,提高了效率。

2.A*算法A*算法是一种常用的启发式搜索算法。

在A*算法中,一个结点位置的好坏用估价函数来对它进行评估。

A*算法的估价函数可表示为:f'(n) = g'(n) + h'(n)这里,f'(n)是估价函数,g'(n)是起点到终点的最短路径值(也称为最小耗费或最小代价),h'(n)是n到目标的最短路经的启发值。

由于这个f'(n)其实是无法预先知道的,所以实际上使用的是下面的估价函数:f(n) = g(n) + h(n)其中g(n)是从初始结点到节点n的实际代价,h(n)是从结点n到目标结点的最佳路径的估计代价。

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

用f(n)作为f'(n)(1)g(n)>=g'(n)的近似,也就是用g(n)代替g'(n),h(n)代替h'(n)。

这样必须满足两个条件:(大多数情况下都是满足的,可以不用考虑),且f必须保持单调递增。

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

第二点特别的重要。

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

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

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

用A*算法解决八数码问题一、 题目:八数码问题也称为九宫问题。

在3×3的棋盘,有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。

棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。

要解决的问题是:任意给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。

二、 问题的搜索形式描述状态:状态描述了8个棋子和空位在棋盘的9个方格上的分布。

初始状态:任何状态都可以被指定为初始状态。

操作符:用来产生4个行动(上下左右移动)。

目标测试:用来检测状态是否能匹配上图的目标布局。

路径费用函数:每一步的费用为1,因此整个路径的费用是路径中的步数。

现在任意给定一个初始状态,要求找到一种搜索策略,用尽可能少的步数得到上图的目标状态算法介绍三、 解决方案介绍1.A*算法的一般介绍A*(A-Star)算法是一种静态路网中求解最短路最有效的方法。

对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即()()()()()()**f g n sqrt dx nx dx nx dy ny dy ny =+--+--;这样估价函数f 在g 值一定的情况下,会或多或少的受估价值h 的制约,节点距目标点近,h 值小,f 值相对就小,能保证最短路的搜索向终点的方向进行。

明显优于盲目搜索策略。

A star算法在静态路网中的应用2.算法伪代码创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。

算起点的估价值,将起点放入OPEN表。

while(OPEN!=NULL){从OPEN表中取估价值f最小的节点n;if(n节点==目标节点){break;}for(当前节点n 的每个子节点X){算X的估价值;if(X in OPEN){if( X的估价值小于OPEN表的估价值 ){把n设置为X的父亲;更新OPEN表中的估价值; //取最小路径的估价值}}if(X inCLOSE){if( X的估价值小于CLOSE表的估价值 ){把n设置为X的父亲;更新CLOSE表中的估价值;把X节点放入OPEN //取最小路径的估价值}}if(X not inboth){把n设置为X的父亲;求X的估价值;并将X插入OPEN表中; //还没有排序}}//end for将n节点插入CLOSE表中;按照估价值将OPEN表中的节点排序; //实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。

}//end while(OPEN!=NULL)保存路径,即从终点开始,每个节点沿着父节点移动直至起点,这就是你的路径.四、源程序#include <iostream>#include <ctime>#include <vector>using namespace std;constint ROW = 3;constint COL = 3;constint MAXDISTANCE = 10000;constint MAXNUM = 10000;int abs(int a){if (a>0) return a;else return -a;}typedefstruct _Node{int digit[ROW][COL];intdist; // 距离intdep; // 深度int index; // 索引值} Node;Node src, dest;vector<Node>node_v; // 储存节点boolisEmptyOfOPEN() { //判断Open表是否空for (inti = 0; i<node_v.size(); i++) {if (node_v[i].dist != MAXNUM)return false;}return true;}boolisEqual(int index, int digit[][COL]) {//判断节点是否与索引值指向的节点相同for (inti = 0; i< ROW; i++)for (int j = 0; j < COL; j++) {if (node_v[index].digit[i][j] != digit[i][j])return false;}return true;}ostream& operator<<(ostream&os, Node& node) {for (inti = 0; i< ROW; i++) {for (int j = 0; j < COL; j++)os<<node.digit[i][j] << ' ';os<<endl;}returnos;}void PrintSteps(int index, vector<Node>&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] <<endl;}void Swap(int& a, int& b) { //交换int t;t = a;a = b;b = t;}void Assign(Node& node, int index) {//获取节点for (inti = 0; i< ROW; i++)for (int j = 0; j < COL; j++)node.digit[i][j] = node_v[index].digit[i][j];}intGetMinNode() {//获取启发值最小的节点intdist = MAXNUM;intloc; // the location of minimize nodefor (inti = 0; i<node_v.size(); i++) {if (node_v[i].dist == MAXNUM)continue;else if ((node_v[i].dist + node_v[i].dep) <dist) { loc = i;dist = node_v[i].dist + node_v[i].dep;}}returnloc;}boolisExpandable(Node& node) {//判断是否可扩展for (inti = 0; i<node_v.size(); i++) {if (isEqual(i, node.digit))return false;}return true;}int Distance(Node& node, int digit[][COL]) {//计算距离int distance = 0;bool flag = false;for(inti = 0; i< ROW; i++)for (int j = 0; j < COL; j++)for (int k = 0; k < ROW; k++) {for (int l = 0; l < COL; l++) {if (node.digit[i][j] == digit[k][l]) {distance += abs(i - k) + abs(j - l); flag = true;break;}elseflag = false;}if (flag)break;}return distance;}intMinDistance(int a, int b) {//二者取小return (a < b ? a : b);}void ProcessNode(int index) {//展开节点int x, y;bool flag;for (inti = 0; i< ROW; i++) {for (int j = 0; j < COL; j++) {if (node_v[index].digit[i][j] == 0) { x =i; y = j;flag = true;break;}else flag = false;}if(flag)break;}Node node_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);}}Node node_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);}}Node node_left;//左移操作Assign(node_left, index);intdist_left = MAXDISTANCE;if (y > 0) {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);}}Node node_right; //右移操作Assign(node_right, index);intdist_right = MAXDISTANCE;if (y < 2) {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;}int main() {int number;cout<< "输入初始状态:" <<endl; for (inti = 0; i< ROW; i++)for (int j = 0; j < COL; j++) { cin>> number;src.digit[i][j] = number;}src.index = 0;src.dep = 1;cout<< "输入目标状态" <<endl; for (int m = 0; m < ROW; m++) for (int n = 0; n < COL; n++) { cin>> number;dest.digit[m][n] = number;}node_v.push_back(src);while (1) {if (isEmptyOfOPEN()) {cout<< "找不到解!" <<endl;return -1;}else {intloc; // the location of the minimize node loc = GetMinNode();if(isEqual(loc, dest.digit)) {vector<Node>rstep_v;cout<< "初始状态:" <<endl;cout<<src<<endl;PrintSteps(loc, rstep_v);cout<< "成功!" <<endl;break;}elseProcessNode(loc);}}return 0;}欢迎您的下载,资料仅供参考!致力为企业和个人提供合同协议,策划案计划书,学习资料等等打造全网一站式需求。

相关文档
最新文档