启发式图搜索
- 格式:ppt
- 大小:170.51 KB
- 文档页数:41
图搜索策略112----⎧⎪⎧⎪⎨⎪⎩⎪⎪⎧⎪⎪⎪⎪⎪⎨⎨⎪⎪⎪⎩⎪⎪⎪⎪⎪⎧⎪⎨⎪⎩⎩⎧⎪⎨⎪⎩一、图搜索概论:①,树的定义和基本术语,图的意义②,图的存储结构2,图的定义1,顶点,2,边,③,显示图的常用术图搜索回顾3,图,4,数据元素隐式图术语,子集树,,排列树二、状态图搜索:①,搜索定义②,搜索树定义广度优先盲目穷举式深度优先有界深度优先全局择优1,树式搜索局部择优分启发式状态图搜索③,搜索方式分类*--A --121*2 4A ⎧⎧⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎩⎩⎪⎧⎪⎧⎪⎨⎪⎪⎩⎪⎨⎪⎧⎪⎪⎨⎪⎪⎩⎩⎩⎧⎧⎧⎪⎪⎨⎨⎪⎩⎨⎪⎪⎩⎪⎩A Beam Search 支界限最近择优算法算法随机碰撞盲目回溯穷举2,线式搜索不回溯启发式可回溯深度优先搜索穷举式搜索,盲目搜索广度优先搜索④,搜索策略盲目碰撞搜索,启发式搜索,⑤搜搜寻算法,3,二分取中查索法找算法算, ⎧⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎩⎩Branch and bound1 2⎧⎨⎩⎧⎨⎩1,猴子与香蕉三,简单实例回顾:2,猴子与香蕉的状态空间图,图搜索一般过程四,图搜索过程,图搜索框过程框图五,通过文章加深图搜索策略(《人工智能图搜索策略的研究》)一,图搜索概论:①图搜索回顾:1.11.2②图的存储结构:1.11.2③图及其术语:1.11.2显示图与隐式图:1.3,显示图的常用术语:1.4隐式图术语二,状态图搜索:①,搜索定义,②,搜索树定义:③,搜索方式分类:④图搜索策略:1.1盲目式搜索:1.2启发式搜索:⑤图搜索算法1.1树搜索方法1.3树搜索举例1.4状态图搜索:1.5状态图搜索举例⑥,常见搜索算法下面是一些比较重要的算法,原文罗列了32个,但我觉得有很多是数论里的或是比较生僻的,和计算机的不相干,所以没有选取。
启发式图搜索过程姓名:学号:启发式图搜索过程一、过程A描述:① OPEN := (s), f(s) := g(s) + h(s);② LOOP : IF OPEN=() THEN EXIT(FAIL);③ n := FIRST(OPEN);④ IF GOAL(n) THEN EXIT(SUCCESS);⑤ REMOVE(n, OPEN) , ADD(n, CLOSED);⑥ EXPAND(n) {m i} , 计算f(n, m i) = g(n, m i) + h(m i); g(n, m i)是从s通过n 到m i的耗散值,f(n, m i)是从s通过n、m i到目标节点耗散值的估计;·ADD(m j , OPEN), 标记m i到n的指针。
·IF f(n, m k)<f(m k) THEN f(m k) := f(n, m k),标记m k到n的指针;比较f(n, m k)和f(m k),f(m k)是扩展n之前计算的耗散值。
·IF f(n, m l)<f(m1) THEN f(m l) := f(n, m l),标记m l到n的指针,ADD(m l,OPEN);当f(n, m l)<f(m l)时,把m l重放回OPEN中,不必考虑修改到其子节点的指针。
⑦ OPEN中的节点按f值从小到大排列;⑧ GO LOOP。
二、最佳图搜索算法A*:当在算法A的评价函数中,使用的启发函数h(n)是处在h*(n)的下界范围,即满足h(n)<=h*(n)时,则把这个算法称为算法A*。
在下面解决八数码问题的程序中,采用h(n)=P(n), P(n)定义为每一个将牌与其目标位置之间的距离的总和。
三、算法实现(1)数据结构class StateNode{public:int gs,hs,fs; //分别表示算法中的g(n)、h(n)、f(n) StateNode *psn; //一个指向扩展出它的父节点的指针StateNode(); //构造函数,初始化节点void putstartnode(); //输入开始节点void putgoalnode(); //输入目标节点int getnode(int i,int j); //读取node[i][j]void swap(int i,int j,int m,int n);//交换数组中指定位置的两个元素的数值bool operator ==(StateNode &sn);//重载了运算符==,方便后面进行比较void operator =(StateNode &sn);//重载了运算符=,方便后面对节点进行整体赋值void printstatenode();//将每个节点的内容按照一定格式输出private:int node[3][3]; //八数码的每个节点用一个二维数组存储};void evaluatefunction(StateNode &sn,StateNode &goal);//启发函数,计算某个节点的h(n)值bool isgoal(StateNode &sn,StateNode &goal);//判断当前节点是否目标节点bool uninlist(StateNode &sn,list<StateNode> &lsn);//判断当前节点是不是在OPEN表或者CLOSED表中void addtolist(StateNode &sn,list<StateNode> &lsn,list<StateNode> &lcsn);//根据当前扩展到的节点的类型(mj,mk,ml)选择不同的操作方式void expandnode(StateNode &sn,StateNode &goal,list<StateNode> &lsn,list<StateNode> &lcsn);//扩展节点,计算节点的评价函数值,根据新的节点的类型选择不同的操作list<StateNode> OPEN; //使用STL中的list类型来存放OPEN 表list<StateNode> CLOSED; //使用STL中的list类型来存放CLOSED表(2)运行过程演示:四、程序代码(C++):#include <iostream>#include <list>#include <math.h>using namespace std;#define MAXNUM 1000class StateNode //这是一个节点类型的类,定义了与节点相关的信息及函数{public:int gs,hs,fs;StateNode *psn;StateNode(){gs=0;hs=0;fs=gs+hs;psn=0;for (int i=0;i<3;i++){for (int j=0;j<3;j++){node[i][j]=0;}}}void putstartnode(){cout<<"请输入目标状态!(空闲的格子用0表示)"<<endl;for (int i=0;i<3;i++){for (int j=0;j<3;j++){cin>>node[i][j];}}cout<<endl;}void putgoalnode(){cout<<"请输入初始状态!(空闲的格子用0表示)"<<endl;for (int i=0;i<3;i++){for (int j=0;j<3;j++){cin>>node[i][j];}}cout<<endl;}int getnode(int i,int j) //读取node[i][j]{return node[i][j];}void swap(int i,int j,int m,int n) //交换数组中指定位置的两个元素的数值{int temp;temp=node[i][j];node[i][j]=node[m][n];node[m][n]=temp;}bool operator ==(StateNode &sn) //重载了运算符==,方便后面进行比较{int n=0;for (int i=0;i<3;i++){for (int j=0;j<3;j++){if (node[i][j]==sn.getnode(i,j)){n++;}}}if (n<9){return false;}else return true;}void operator =(StateNode &sn) //重载了运算符=,方便后面对节点进行整体赋值{for (int i=0;i<3;i++){for (int j=0;j<3;j++){node[i][j]=sn.getnode(i,j);}}this->gs=sn.gs;this->hs=sn.hs;this->fs=sn.fs;this->psn=sn.psn;}void printstatenode() //将每个节点的内容按照一定格式输出{for (int i=0;i<3;i++){for (int j=0;j<3;j++){cout<<node[i][j]<<" ";}cout<<"\n";}}protected:private:int node[3][3];};void evaluatefunction(StateNode &sn,StateNode &goal) //启发函数,计算某个节点的h(n)值{for (int i=0;i<3;i++){for (int j=0;j<3;j++){if (sn.getnode(i,j)!=goal.getnode(i,j) && sn.getnode(i,j)!=0){for (int m=0;m<3;m++){for (int n=0;n<3;n++){if (sn.getnode(i,j)==goal.getnode(m,n)){sn.hs+=(abs(i-m)+abs(j-n));}}}}}}}bool isgoal(StateNode &sn,StateNode &goal) //判断当前节点是否目标节点{return sn==goal;}bool uninlist(StateNode &sn,list<StateNode> &lsn){ //判断当前节点是不是在OPEN表或者CLOSED表中list<StateNode>::iterator iter;for (iter=lsn.begin();iter!=lsn.end();iter++){if (*iter==sn){return false;}}return true;}void addtolist(StateNode &sn,list<StateNode> &lsn,list<StateNode> &lcsn){ //根据当前扩展到的节点的类型(mj,mk,ml)选择不同的操作方式list<StateNode>::iterator iter;list<StateNode>::iterator iterc;if (uninlist(sn,lsn) && uninlist(sn,lcsn)){for (iter=lsn.begin();iter!=lsn.end() && sn.fs>=iter->fs;iter++){}lsn.insert(iter,sn);}else if(!uninlist(sn,lsn)){for (iter=lsn.begin();iter!=lsn.end();iter++){if (*iter==sn) {break;}}if (iter->fs>sn.fs) {*iter=sn;}}else if (!uninlist(sn,lcsn)){for (iterc=lcsn.begin();iterc!=lcsn.end();iterc++){if (*iterc==sn) {break;}}if(iterc->fs>sn.fs){for (iter=lsn.begin();iter!=lsn.end() && sn.fs>=iter->fs;iter++){}lsn.insert(iter,*lcsn.erase(iterc));}}}void evaluandadd(StateNode &temsn,StateNode &sn,StateNode &goal,list<StateNode> &lsn,list<StateNode> &lcsn){temsn.gs=sn.gs+1;temsn.hs=0;evaluatefunction(temsn,goal);temsn.fs=temsn.gs+temsn.hs;addtolist(temsn,lsn,lcsn);}void expandnode(StateNode &sn,StateNode &goal,list<StateNode> &lsn,list<StateNode> &lcsn){ //扩展节点,计算节点的评价函数值,根据新的节点的类型选择不同的操作StateNode temsn;list<StateNode>::iterator iter;for (int i=0;i<3;i++){for (int j=0;j<3;j++){if (sn.getnode(i,j)==0){if (i>0) //向左移动{temsn=sn;temsn.swap(i,j,i-1,j);temsn.psn=&sn;evaluandadd(temsn,sn,goal,lsn,lcsn);}if (i<2) //向右移动{temsn=sn;temsn.swap(i,j,i+1,j);temsn.psn=&sn;evaluandadd(temsn,sn,goal,lsn,lcsn);}if (j>0) //向上移动{temsn=sn;temsn.swap(i,j,i,j-1);temsn.psn=&sn;evaluandadd(temsn,sn,goal,lsn,lcsn);}if (j<2) //向下移动{temsn=sn;temsn.swap(i,j,i,j+1);temsn.psn=&sn;evaluandadd(temsn,sn,goal,lsn,lcsn);}}}}}int main(){StateNode Start,SN[MAXNUM],Goal;int i,j=0;list<StateNode> OPEN;list<StateNode> CLOSED;list<StateNode>::iterator iter;list<StateNode>::iterator iterc;Goal.putgoalnode();Start.putstartnode();evaluatefunction(Start,Goal);Start.gs=0;Start.fs=Start.gs+Start.hs;OPEN.push_back(Start);for (iter=OPEN.begin(),i=0;iter!=OPEN.end() && i<MAXNUM;iter=OPEN.begin(),i++) {if (OPEN.empty()) {return 0;}SN[i]=OPEN.front();if (isgoal(SN[i],Goal)){cout<<"搜索过程如下所示:"<<endl;for (StateNode *tempsn=&SN[i];!(*tempsn==Start);tempsn=tempsn->psn,j++){cout<<"第"<<j<<"步搜索:"<<endl;tempsn->printstatenode();cout<<endl;}cout<<"第"<<j<<"步搜索:"<<endl;Start.printstatenode();return 1;}OPEN.pop_front();CLOSED.push_back(SN[i]);if (CLOSED.size()>MAXNUM){cout<<"该初始节点不可扩展至目标节点!"<<endl;return 0;}expandnode(SN[i],Goal,OPEN,CLOSED);}return 0;(注:可编辑下载,若有不当之处,请指正,谢谢!)。
启发式图搜索算法摘要:启发式搜索策略概述和有序搜索。
启发式搜索弥补盲目搜索的不足,提高搜索效率。
一种方法用于排列待扩展节点的顺序,即选择最有希望的节点加以扩展,那么,搜索效率将会大为提高。
进行搜索技术一般需要某些有关具体问题领域的特性的信息。
关键词:启发式搜索;估价函数;有序搜索;A*算法;正文:启发式图搜索的意义因为无信息图搜索算法的效率低,耗费过多的计算空间与时间,这是组合爆炸的一种表现形式。
所以引入了启发式图搜索算法。
启发式图搜索算法就是进行搜索技术一般需要某些有关具体问题领域的特性的信息,把此种信息叫做启发信息。
利用启发信息的搜索方法叫做启发式搜索方法。
关于图搜索的启发式搜索算法就叫做启发式图搜索算法。
启发式图搜索策略:假设初始状态、算符和目标状态的定义都是完全确定的,然后决定一个搜索空间。
因此,问题就在于如何有效地搜索这个给定空间。
启发信息按其用途可分为下列3种:(1) 用于决定要扩展的下一个节点,以免像在宽度优先或深度优先搜索中那样盲目地扩展。
(2) 在扩展一个节点的过程中,用于决定要生成哪一个或哪几个后继节点,以免盲目地同时生成所有可能的节点。
(3) 用于决定某些应该从搜索树中抛弃或修剪的节点。
启发信息的状态空间搜索算法,即决定哪个是下一步要扩展的节点。
这种搜索总是选择“最有希望”的节点作为下一个被扩展的节点。
这种搜索叫做有序搜索(ordered search)。
有关具体问题领域的信息常常可以用来简化搜索。
一个比较灵活(但代价也较大)的利用启发信息的方法是应用某些准则来重新排列每一步OPEN表中所有节点的顺序。
然后,搜索就可能沿着某个被认为是最有希望的边缘区段向外扩展。
应用这种排序过程,需要某些估算节点“希望”的量度,这种量度叫做估价函数(evalution function)。
所谓的估价函数就是为获得某些节点“希望”的启发信息,提供一个评定侯选扩展节点的方法,以便确定哪个节点最有可能在通向目标的最佳路径上。