用A算法解决八数码问题演示教学
A星算法求解八数码技术报告

A*算法求解八数码问题●open 表、closed 表数据结构的选择:1)把s放入open表,记f=h,令closed为空表。
2)重复下列过程,直到找到目标节点为止。
若open表为空表,则宣告失败。
3)选取open表中未设置过的具有最小f值的节点为最佳节点bestnode,并把它放入closed表。
4)若bestnode为一目标节点,则成功求得一解。
5)若bestnode不是目标节点,则扩展之,产生后继节点succssor。
6)对每个succssor进行下列过称:a)对每个succssor返回bestnode的指针。
b)计算g(suc)=g(bes)+k(bes,suc)。
c)如果succssore open,称此节点为old,并填到bestnode的后继节点表中。
d)比较新旧路劲代价。
如果g(suc)<g(old),则重新确定old的父辈节点为bestnode,记下较小代价g(old),并修真f(old)值。
e)若至old节点的代价较低或一样,则停止扩展节点。
f)若succssore不再closed表中,则看其是否在closed表中。
g)若succssore在closed表中,则转向(c)。
h)若succssore既不在open表中,又不在closed表中,则把它放入open表中,并添入bestnode后裔表中,然后转向(7)。
i)计算f值j)Go loop●节点的数据结构:static int target[9]={1,2,3,8,0,4,7,6,5}; 全局静态变量,表示目标状态class eight_num{private:int num[9]; 定义八数码的初始状态int not_in_position_num; 定义不在正确位置八数码的个数int deapth; 定义了搜索的深度int eva_function; 评价函数的值,每次选取最小的进行扩展public:eight_num* parent; 指向节点的父节点eight_num* leaf_next; 指向open表的下一个节点eight_num* leaf_pre; 指向open 表的前一个节点初始状态的构造函数eight_num(int init_num[9]);eight_num(int num1,int num2,int num3,int num4,int num5,int num6,int num7,int num8,int num9){}eight_num(void){ }计算启发函数g(n)的值void eight_num::cul_para(void){}显示当前节点的状态void eight_num::show(){}复制当前节点状态到一个另数组中void eight_num::get_numbers_to(int other_num[9]){}设置当前节点状态(欲设置的状态记录的other数组中)void eight_num::set_num(int other_num[9]){}eight_num& eight_num::operator=(eight_num& another_8num){} eight_num& eight_num::operator=(int other_num[9]){}int eight_num::operator==(eight_num& another_8num){}int eight_num::operator==(int other_num[9]){}空格向上移int move_up(int num[9]){}空格向下移int move_down(int num[9]){}空格向左移int move_left(int num[9]){}空格向右移int move_right(int num[9]){}判断可否解出int icansolve(int num[9],int target[9]){}判断有无重复int existed(int num[9],eight_num *where){}寻找估价函数最小的叶子节点eight_num* find_OK_leaf(eight_num* start){}}A*算法求解框图:●分析估价函数对搜索算法的影响:估价函数就是评价函数,它用来评价子结点的好坏,因为准确评价是不可能的,所以称为估值。
八数码难题的搜索求解演示-推荐下载

九宫问题的求解方法就是交换空格(0)位置,直至到达目标 位置为止。如图所示:
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术通关,1系电过,力管根保线据护敷生高设产中技工资术艺料0不高试仅中卷可资配以料置解试技决卷术吊要是顶求指层,机配对组置电在不气进规设行范备继高进电中行保资空护料载高试与中卷带资问负料题荷试2下卷2,高总而中体且资配可料置保试时障卷,各调需类控要管试在路验最习;大题对限到设度位备内。进来在行确管调保路整机敷使组设其高过在中程正资1常料中工试,况卷要下安加与全强过,看度并22工且22作尽22下可22都能22可地护以缩1关正小于常故管工障路作高高;中中对资资于料料继试试电卷卷保破连护坏接进范管行围口整,处核或理对者高定对中值某资,些料审异试核常卷与高弯校中扁对资度图料固纸试定,卷盒编工位写况置复进.杂行保设自护备动层与处防装理腐置,跨高尤接中其地资要线料避弯试免曲卷错半调误径试高标方中高案资等,料,编试要5写、卷求重电保技要气护术设设装交备备置底4高调、动。中试电作管资高气,线料中课并敷3试资件且、设卷料中拒管技试试调绝路术验卷试动敷中方技作设包案术,技含以来术线及避槽系免、统不管启必架动要等方高多案中项;资方对料式整试,套卷为启突解动然决过停高程机中中。语高因文中此电资,气料电课试力件卷高中电中管气资壁设料薄备试、进卷接行保口调护不试装严工置等作调问并试题且技,进术合行,理过要利关求用运电管行力线高保敷中护设资装技料置术试做。卷到线技准缆术确敷指灵设导活原。。则对对:于于在调差分试动线过保盒程护处中装,高置当中高不资中同料资电试料压卷试回技卷路术调交问试叉题技时,术,作是应为指采调发用试电金人机属员一隔,变板需压进要器行在组隔事在开前发处掌生理握内;图部同纸故一资障线料时槽、,内设需,备要强制进电造行回厂外路家部须出电同具源时高高切中中断资资习料料题试试电卷卷源试切,验除线报从缆告而敷与采设相用完关高毕技中,术资要资料进料试行,卷检并主查且要和了保检解护测现装处场置理设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
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)# 如果该节点是目标节点,则搜索结束;否则,将扩展出来的新节点加入优先队列中。
八数码难题的搜索求解演示

人工智能实验报告学院:信息科学与工程学院班级:自动化0901班学号: 0909090316姓名:孙锦岗指导老师:刘丽珏日期:2011年12月20日一、实验名称、目的及内容实验名称:八数码难题的搜索求解演示实验目的:加深对图搜索策略概念的理解,掌握搜索算法。
实验内容要求:以八数码难题为例演示广度优先或深度优先搜索、A算法(本实验使用的是广度优先搜索)的搜索过程,争取做到直观、清晰地演示算法。
八数码难题:在3×3方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的八张牌,初始状态S0,目标状态如图所示,可以使用的操作有:空格上移,空格左移,空格右移,空格下移。
试编一程序实现这一搜索过程。
二、实验原理及基本技术路线图实验原理:八数码问题中,程序产生的随机排列转换成目标共有两种可能,而且这两种不可能同时成立,也就是奇数排列和偶数排列。
我们可以把一个随机排列的数组从左到右从上到下用一个数组表示,例如{8,7,1,5,2,6,3,4,0}其中0代表空格。
它在奇序列位置上。
在这个数组中我们首先计算它能够重排列出来的结果,公式就是:∑(F(X))=Y,其中F(X),就是一个数他前面比这个数小的数的个数,Y为奇数和偶数个有一种解法。
那么上面的数组我们就可以解出它的结果。
数据结构:本实验使用的数据结构是队列,应用队列先进先出的特点来实现对节点的保存和扩展。
首先建立一个队列,将初始结点入队,并设置队列头和尾指,然后取出队列(头指针所指)的结点进行扩展,从它扩展出子结点,并将这些结点按扩展的顺序加入队列,然后判断扩展出的新结点与队列中的结点是否重复,如果重复则,否则记录其父结点,并将它加入队列,更新队列尾指针,然后判断扩展出的结点是否是目标结点,如果是则显示路径,程序结束。
否则如果队列头的结点可以扩展,直接返回第二步。
否则将队列头指针指向下一结点,再返回第二步,知道扩展出的结点是目标结点结束,并显示路径。
用A算法实现的八数码问题C++源码

用A算法实现的八数码问题C++源码用A*算法实现的八数码问题C++源码#include <iomanip>#include <stdlib.h>#include <iostream.h>#include <time.h>#include <stdio.h>#include <conio.h>//using namespace std;//定义默认目标状态static int target[9]={1,2,3,8,0,4,7,6,5};//八数码类class EightNum{private:int num[9];int diffnum;//与目标状态位置不同的数的个数. int deapth;//派生的深度.int evalfun;//状态的估价值public:EightNum *parent;//生成当前状态的父状态. EightNum *state_pre;//当前状态前生成状态. EightNum *state_next;//当前状态后生成状态.//成员函数声明EightNum(void);EightNum(int initnum[9]);int get_evalfun();void eval_func();void getnum(int num1[9]);void setnum(int num1[9]);void show(void);void show_spec(int i);int null_position(void);EightNum& operator =(EightNum& NewEightN);EightNum& operator =(int num2[9]);int operator ==(EightNum& NewEightN);int operator ==(int num2[9]);};//八数码类定义//八数码类成员函数定义EightNum::EightNum(void){//初始化数组num[]for(int i=0;i<9;i++)num[i]=i;}EightNum::EightNum(int initnum[9]){//用输入的数组初始化num[]for(int i=0;i<9;i++)num[i]=initnum[i];}int EightNum::get_evalfun(){//返回估价值return evalfun;}void EightNum::eval_func(){//估价函数int i,temp;temp=0;for(i=0;i<9;i++){if(num[i]!=target[i])temp++;}diffnum=temp;if(this->parent==NULL) deapth=0;else deapth=this->parent->deapth+1;evalfun=deapth+temp;}void EightNum::getnum(int num1[9]){//取出八数码数值for(int i=0;i<9;i++)num1[i]=num[i];}void EightNum::setnum(int num1[9]){//写入八数码数值for(int i=0;i<9;i++)num[i]=num1[i];}void EightNum::show(){//八数码输出函数for(int i=0;i<9;i++){cout<<num[i]<<" ";if((i+1)%3==0)cout<<"\n";}}void EightNum::show_spec(int i){//结果步骤输出函数cout<<num[i];cout<<"<--";}int EightNum::null_position(){//查找空格位置int i,j;for(i=0;i<9;i++){if(num[i]==0)j=i;}return j;}EightNum& EightNum::operator =(EightNum& NewEightN){//"="重载,针对八数码类的引用for(int i=0;i<9;i++)num[i]=NewEightN.num[i];diffnum=NewEightN.diffnum;deapth=NewEightN.deapth+1;evalfun=diffnum+deapth;return *this;}EightNum& EightNum::operator =(int num2[9]){//"="重载,用于数组赋值for(int i=0;i<9;i++)num[i]=num2[i];return *this;}int EightNum::operator ==(EightNum& NewEightN){//"=="重载,用于八数码类中状态的比较int compere=1;for(int i=0;i<9;i++)if(num[i]!=NewEightN.num[i]){compere=0;break;}if(compere==0) return 0;else return 1;}int EightNum::operator ==(int num2[9]){//"=="重载,用于数组的比较int compere=1;for(int i=0;i<9;i++)if(num[i]!=num2[i]){compere=0;break;}if(compere==0) return 0;else return 1;}//八数码类函数定义结束int solve(int num[9],int target[9]){//判断是否有解的函数,利用逆序数的奇偶性来判断int i,j;int num_con=0,tar_con=0;for(i=0;i<9;i++)for(j=0;j<i;j++){if(num[j]<num[i] && num[j]!=0)num_con++;if(target[j]<target[i] && target[j]!=0)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))return 1;elsereturn 0;}//空格移动函数int moveup(int num[9]){//空格上移for(int i=0;i<9;i++)if(num[i]==0) break;if(i<3) return 0;else {num[i]=num[i-3];num[i-3]=0;return 1;}}int movedown(int num[9]){//空格下移for(int i=0;i<9;i++)if(num[i]==0) break;if(i>5) return 0;else {num[i]=num[i+3];num[i+3]=0;return 1;}}int moveleft(int num[9]){//空格左移for(int i=0;i<9;i++)if(num[i]==0) break;if(i==0||i==3||i==6) return 0;else {num[i]=num[i-1];num[i-1]=0;return 1;}}int moveright(int num[9]){//空格右移for(int i=0;i<9;i++)if(num[i]==0) break;if(i==2||i==5||i==8) return 0;else {num[i]=num[i+1];num[i+1]=0;return 1;}}int exist(int num[9],EightNum *a){//判断是否重复搜索函数EightNum *t;for(t=a;t!=NULL;t=t->parent)if(*t==num) return 1;//调用"=="进行数组比较else return 0;}EightNum* find(EightNum *s){//寻找估价函数值最小的节点EightNum *m,*n;int min=s->get_evalfun();m=n=s;for(m=s;m!=NULL;m=m->state_next){if(min>m->get_evalfun()){n=m;min=m->get_evalfun();}return n;}}int main(void)//主函数{int i,j;int flag;int num[9];int error;do{//输入判断error=0;cout<<"请输入八数码问题的初始状态(用0代表空格,中间用空格隔开):"<<endl;for(i=0;i<9;i++){flag=0;cin>>num[i];for(j=0;j<i;j++)if(num[j]==num[i])flag=1;if(num[i]<0||num[i]>8||flag==1){error++;}}if(error!=0)cout<<"输入数据错误!请重新输入!"<<endl;}while(error!=0);cout<<"是否改变默认的目标状态?(y/n)";char input;cin>>input;int error1;if(input=='y'||input=='Y'){do{error1=0;cout<<"请输入新的目标状态(用0代表空格):"<<endl;for(i=0;i<9;i++){flag=0;cin>>target[i];for(j=0;j<i;j++)if(target[j]==target[i])flag=1;if(target[i]<0||target[i]>9||flag==1){error1++;}}if(error1!=0)cout<<"输入数据错误!请重新输入!"<<endl;}while(error1!=0);}//实例化初始状态和目标状态,并输出.EightNum start(num),T arget(target);start.parent=start.state_next=start.state_pre=NULL; start.eval_func();cout<<"初始状态为:"<<endl;start.show();cout<<"目标状态为:"<<endl;Target.show();//判断是否有解int m=solve(num,target);if(m==0){cout<<"此状态无解!"<<endl;return 0;}//进入A*算法搜索double time;clock_t startt,finisht;int ok=0;//结束标识位int space=0;//所耗费空间startt=clock();//开始时间EightNum *BestNode=&start,*Node=&start,*New8Num,*r; while(BestNode!=NULL&&ok!=1){BestNode=find(Node);if(*BestNode==Target){//调用"=="操作符ok=1;break;}r=BestNode->state_pre;//生成向上移的节点BestNode->getnum(num);if(moveup(num) && !exist(num,BestNode)){New8Num=new EightNum;New8Num->setnum(num);New8Num->parent=BestNode;New8Num->eval_func();New8Num->state_pre=r;if(r==NULL)Node=New8Num;elser->state_next=New8Num;r=New8Num;space++;}//生成向下移的节点BestNode->getnum(num);if(movedown(num) && !exist(num,BestNode)){ New8Num=new EightNum;New8Num->setnum(num);New8Num->parent=BestNode;New8Num->eval_func();New8Num->state_pre=r;if(r==NULL)Node=New8Num;elser->state_next=New8Num;r=New8Num;space++;}//生成向左移的节点BestNode->getnum(num);if(moveleft(num) && !exist(num,BestNode)){ New8Num=new EightNum;New8Num->setnum(num);New8Num->parent=BestNode;New8Num->eval_func();New8Num->state_pre=r;if(r==NULL)Node=New8Num;elser->state_next=New8Num;r=New8Num;space++;}//生成向右移的节点BestNode->getnum(num);if(moveright(num) && !exist(num,BestNode)){New8Num=new EightNum;New8Num->setnum(num);New8Num->parent=BestNode;New8Num->eval_func();New8Num->state_pre=r;if(r==NULL)Node=New8Num;elser->state_next=New8Num;r=New8Num;space++;}r->state_next=BestNode->state_next;if(BestNode->state_next!=NULL)BestNode->state_next->state_pre=r;BestNode->state_next=BestNode->state_pre=NULL; }finisht=clock();//输出搜索结果if(ok==1){time=(double)(finisht-startt)*1000/CLOCKS_PER_SEC; EightNum *p,*q=NULL;int step=0;for(p=BestNode->parent;p!=NULL;p->parent){if(step==0){i=8;p->show_spec(i);i=p->null_position();}else{p->show_spec(i);i=p->null_position();}if (step==8||step==18||step==28||step==38||step==48) cout<<"\n";step++;}cout<<"\nA*算法处理结果:所耗时间:";cout<<time;cout<<"ms, ";cout<<"所耗空间:";cout<<space;cout<<"块, ";cout<<"最短路径步数:";cout<<step;cout<<"步 !\n";}elsecout<<"\nA*算法无法找到最短路径!\n";}。
八数码问题C语言A星算法详细实验报告含代码【范本模板】

一、实验内容和要求八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。
例如:图1 八数码问题示意图请任选一种盲目搜索算法(广度优先搜索或深度优先搜索)或任选一种启发式搜索方法(全局择优搜索,加权状态图搜索,A 算法或A*算法)编程求解八数码问题(初始状态任选)。
选择一个初始状态,画出搜索树,填写相应的OPEN 表和CLOSED表,给出解路径,对实验结果进行分析总结,得出结论。
二、实验目的1. 熟悉人工智能系统中的问题求解过程;2. 熟悉状态空间的盲目搜索和启发式搜索算法的应用;3. 熟悉对八数码问题的建模、求解及编程语言的应用。
三、实验算法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)的近似,也就是用g(n)代替g'(n),h(n)代替h'(n)。
这样必须满足两个条件:(1)g(n)〉=g’(n)(大多数情况下都是满足的,可以不用考虑),且f必须保持单调递增。
(2)h必须小于等于实际的从当前节点到达目标节点的最小耗费h(n)<=h'(n).第二点特别的重要。
可以证明应用这样的估价函数是可以找到最短路径的。
A算法ppt课件

f(S2)=d(S2)+W(S2)=2+2=4 从图1还可以看出,该问题的解为 S0 →S1 →S2 →S3 →Sg
5
图1 八数码难题的全局择优搜索树
6
7
2.局部择优搜索
对这一算法进一步分析也可以发现:如果取估 价函数f(n)=g(n),则它将退化为代价树的深度 优先搜索;如果取估价函数f(n)=d(n),则它将 退化为深度优先搜索。可见,深度优先搜索和 代价树的深度优先搜索是局部择优搜索的两个 特例。
9
A*算法
上一节讨论的启发式搜索算法,都没有 对估价函数f(n)做任何限制。实际上,估 价函数对搜索过程是十分重要的,如果 选择不当,则有可能找不到问题的解, 或者找到的不是问题的最优解。为此, 需要对估价函数进行某些限制。A*算法 就是对估价函数加上一些限制后得到的 一种启发式搜索算法。
退出; (5)若节点n不可扩展,则转到第(2)步; (6)扩展节点n,生成子节点ni(i=1,2,……),计算每一个子节点的
估价值f(ni) (i=1,2,……),并按估价值从小到大的顺序依次放入 Open表的首部,并为每一个子节点设置指向父节点的指针,然后 转第(2)步。
8
由于这一算法的第六步仅仅是把刚生成的子节 点按其估价函数值从小到大放入Open表中,这 样在算法第(3)步取出的节点仅是刚生成的子节 点中估价函数值最小的一个节点。因此,它是 一种局部择优的搜索方式。
2
1. 全局择优搜索
在全局择优搜索中,每当需要扩展节点时,总是从Open表的所有节点中 选择一个估价函数值最小的节点进行扩展。其搜索过程可能描述如下:
用VC++实现基于A_算法的八数码问题

4结论 本程序主要是用A*算法来搜索八数码问题的最优
解。通过输入大量的初始状态和目标状态发现,在一般情 况下都可以找到最优的动作序列,但对某些复杂的初始状 态虽能得到正确解却不能完全得到最短的搜索路径。这
是有待改进的地方。
int result=0:
f or(i=0;i<3;i++)
{ for(j=0;j<3;j++) { XClJl'[cur-->state[i][j]]_i; ycur[cur->state[i][j]]-j; xdest[dest一>state[i][j]]_i;
(上接第31页) 当的优化及处理,可以进一步发挥SVM本身处理问题的 优越性。
表1数据实验结果表
训练集预处理前
训练集预处理后
呵’了
实际结果 预测结果 总耗时(s) 实际结果 预测结果 总耗时(s)
1
+l
+l
+lLeabharlann +12+13
+1
4
+1
5
+1
6
一l
7
一l
8
—1
9
—1
+1 +1 +l +l ‘1’ +1。 —1 —1
pmbldn.Then it"笔xplains the definition of algorithm A*and makes it clear how to impmve the efficiency of search and describe the Go—
rithm A。which is one of heuristic search based On graphsearch.According tO this algorithm display the process of exploring the Eight—
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
用A算法解决八数码问题 精品资料
仅供学习与交流,如有侵权请联系网站删除 谢谢2 用A*算法解决八数码问题 一、 题目:八数码问题也称为九宫问题。在3×3的棋盘,有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。要解决的问题是:任意给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。 二、 问题的搜索形式描述 状态:状态描述了8个棋子和空位在棋盘的9个方格上的分布。 初始状态:任何状态都可以被指定为初始状态。 操作符:用来产生4个行动(上下左右移动)。 目标测试:用来检测状态是否能匹配上图的目标布局。 路径费用函数:每一步的费用为1,因此整个路径的费用是路径中的步数。 现在任意给定一个初始状态,要求找到一种搜索策略,用尽可能少的步数得到上图的目标状态算法介绍 三、 解决方案介绍 1.A*算法的一般介绍 A*(A-Star)算法是一种静态路网中求解最短路最有效的方法。对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即 **fgnsqrtdxnxdxnxdynydyny;
这样估价函数f在g值一定的情况下,会或多或少的受估价值h的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行。明显优于盲目搜索策略。 精品资料
仅供学习与交流,如有侵权请联系网站删除 谢谢3 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表的估价值 ) 精品资料 仅供学习与交流,如有侵权请联系网站删除 谢谢4 {把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 #include #include
using namespace std;
constint ROW = 3; constint COL = 3; constint MAXDISTANCE = 10000; constint MAXNUM = 10000; 精品资料 仅供学习与交流,如有侵权请联系网站删除 谢谢5
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; vectornode_v; // 储存节点 boolisEmptyOfOPEN() { //判断Open表是否空 for (inti = 0; iif (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; } 精品资料 仅供学习与交流,如有侵权请联系网站删除 谢谢6 return true; }
ostream& operator<<(ostream&os, Node& node) { for (inti = 0; i< ROW; i++) { for (int j = 0; j < COL; j++) os void PrintSteps(int index, 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 " <<} void Swap(int& a, int& b) { //交换 int t; t = a; a = b; 精品资料 仅供学习与交流,如有侵权请联系网站删除 谢谢7 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 node for (inti = 0; iif (node_v[i].dist == MAXNUM) continue; else if ((node_v[i].dist + node_v[i].dep) loc = i; dist = node_v[i].dist + node_v[i].dep; } } returnloc; } boolisExpandable(Node& node) {//判断是否可扩展 for (inti = 0; iif (isEqual(i, node.digit)) return false; } 精品资料 仅供学习与交流,如有侵权请联系网站删除 谢谢8 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; } else flag = false; } if (flag) break; } return distance; } intMinDistance(int a, int b) {//二者取小 return (a < b ? a : b); } void ProcessNode(int index) {//展开节点