启发式搜索实验.docx
《启发式搜索实验.docx》由会员分享,可在线阅读,更多相关《启发式搜索实验.docx(13页珍藏版)》请在冰豆网上搜索。
启发式搜索实验
实验三搜索推理技术
启发式搜索算法—A*算法
1.实验目的
〔1〕了解搜索推理的相关技术;
〔2〕掌握启发式搜索算法或者基于规那么推理的分析方法。
2.实验容〔2个实验容可以选择1个实现〕
〔1〕启发式搜索算法。
熟悉和掌握启发式搜索的定义、估价函数和算法过程,并求解博弈问题,理解求解流程和搜索顺序;
〔2〕产生式系统实验。
熟悉和掌握产生式系统的运行机制,掌握基于规那么推理的根本方法。
3.实验报告要求
〔1〕简述实验原理及方法,并请给出程序设计流程图。
〔A-Star)算法是一种静态路网中求解最短路最有效的直接搜索方法。
公式表示为:
f(n)=g(n)+h(n),
其中f(n)是从初始点经由节点n到目标点的估价函数,
g(n)是在状态空间中从初始节点到n节点的实际代价,
h(n)是从n到目标节点最正确路径的估计代价。
保证找到最短路径〔最优解的〕条件,关键在于估价函数h(n)的选取:
估价值h(n)<=n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索围大,效率低。
但能得到最优解。
并且如果h(n)=d(n),即距离估计h(n)等于最短距离,那么搜索将严格沿着最短路径进展,此时的搜索效率是最高的。
然后我们通过图文结合的形式来解释下,如下列图:
图中有这么几个要点先需要了解:
1、类似迷宫图,分开场节点(start)、障碍物、完毕节点(end),我们需要从start节点探寻一条到end节点的路线
2、对于探寻的每一步,都会以当前节点为基点,扫描其相邻的八个节点
3、计算当前节点与start节点及到end的距离
4、计算出最短路径
如果明白了上面的场景描述,下面就可以进展分析了。
在A*算法中,核心思想是一个公式,上面已经提到过:
f(n)=g(n)+h(n)
〔2〕源程序清单:
package.itxxz.ui.suanfa.astar;
importjava.util.Iterator;
importjava.util.LinkedList;
importjava.util.Queue;
import.itxxz.ui.suanfa.astar.Point;
publicclassItxxzAstar{
//开场节点
privatePointstartPoint=null;
//当前节点
privatePointendPoint=null;
//完毕节点
privatePointcurrentPoint=null;
//最短距离坐标节点
privatePointshortestFPoint=null;
//迷宫数组地图
privatestaticfinalint[][]mazeArray={
{1,0,0,0,0},
{1,0,2,0,0},
{1,0,0,0,1},
{1,0,0,0,0},
{1,1,1,1,0},
{1,0,0,0,0},
{3,0,1,1,1}};
//迷宫坐标对象
privatePoint[][]mazePoint=null;
//开启队列,用于存放待处理的节点
QueueopenQueue=null;
//关闭队列,用于存放已经处理过的节点
QueueclosedQueue=null;
//起始节点到某个节点的距离
int[][]FList=null;
//某个节点到目的节点的距离
int[][]GList=null;
//起始节点经过某个节点到目的节点的距离
int[][]HList=null;
/**
*构造函数
*
*parammaze
*迷宫图
*paramstartPoint
*起始节点
*paramendPoint
*完毕节点
*/
publicItxxzAstar(Point[][]mazePoint,PointstartPoint,PointendPoint){
this.mazePoint=mazePoint;
this.startPoint=startPoint;
this.endPoint=endPoint;
openQueue=newLinkedList();
openQueue.offer(startPoint);
closedQueue=newLinkedList();
FList=newint[mazePoint.length][mazePoint[0].length];
GList=newint[mazePoint.length][mazePoint[0].length];
HList=newint[mazePoint.length][mazePoint[0].length];
for(inti=0;ifor(intj=0;jFList[i][j]=Integer.MAX_VALUE;
GList[i][j]=Integer.MAX_VALUE;
HList[i][j]=Integer.MAX_VALUE;
}
}
//起始节点到当前节点的距离
GList[startPoint.getX()][startPoint.getY()]=0;
//当前节点到目的节点的距离
HList[startPoint.getX()][startPoint.getY()]=getPointDistance(
startPoint.getX(),startPoint.getY(),endPoint.getX(),
endPoint.getY());
//f(x)=g(x)+h(x)
FList[startPoint.getX()][startPoint.getY()]=GList[startPoint.getX()][startPoint
.getY()]+HList[startPoint.getX()][startPoint.getY()];
}
/**
*计算当前坐标与完毕坐标之间的距离
*
*计算方法为每向相信坐标移动一次算作一个距离单位
*
*/
privateintgetPointDistance(intcurrent_x,intcurrent_y,intend_x,
intend_y){
returnMath.abs(current_x-end_x)+Math.abs(current_y-end_y);
}
/**
*数组迷宫地图
*
*0、可通行1、障碍2、开场节点3、完毕节点
*
*/
publicstaticvoidmain(String[]args){
//创立节点迷宫图
Point[][]mazePoint=newPoint[mazeArray.length][mazeArray[0].length];
for(inti=0;ifor(intj=0;jmazePoint[i][j]=newPoint(i,j,mazeArray[i][j]);
}
}
Pointstart=mazePoint[1][2];
Pointend=mazePoint[6][0];
ItxxzAstarstar=newItxxzAstar(mazePoint,start,end);
star.start();
System.out.println(mazeArray.length+","+mazeArray[0].length);
star.printPath();
}
/**
*开场迷宫搜索
*
*/
publicvoidstart(){
while((currentPoint=findShortestFPoint())!
=null){
if(currentPoint.getX()==endPoint.getX()
&¤tPoint.getY()==endPoint.getY())
return;
updateNeighborPoints(currentPoint);
}
}
/**
*获取距离最短的坐标点
*
*/
publicPointfindShortestFPoint(){
currentPoint=null;
shortestFPoint=null;
intshortestFValue=Integer.MAX_VALUE;
Iteratorit=openQueue.iterator();
while(it.hasNext()){
currentPoint=it.next();
if(FList[currentPoint.getX()][currentPoint.getY()]<=shortestFValue){
shortestFPoint=currentPoint;
shortestFValue=FList[currentPoint.getX()][currentPoint.getY()];
}
}
if(shortestFValue!
=Integer.MAX_VALUE){
System.out
.println("【移除节点】:
"+shortestFPoint.getValue()+"["
+shortestFPoint.getX()+","
+shortestFPoint.getY()+"]");
openQueue.remove(shortestFPoint);
closedQueue.offer(shortestFPoint);
}
returnshortestFPoint;
}
/**
*更新临近节点
*/
privatevoidupdateNeighborPoints(PointcurrentPoint){
intcurrent_x=currentPoint.getX();
intcurrent_y=currentPoint.getY();
System.out.println("当前节点:
["+current_x+","+current_y+"]");
//上
if(checkPosValid(current_x-1,current_y)){
System.out.print("上");
updatePoint(mazePoint[current_x][current_y],
mazePoint[current_x-1][current_y]);
}
//下
if(checkPosValid(current_x+1,current_y)){
System.out.print("下");
updatePoint(mazePoint[current_x][current_y],
mazePoint[current_x+1][current_y]);
}
//左
if(checkPosValid(current_x,current_y-1)){
System.out.print("左");
updatePoint(mazePoint[current_x][current_y],
mazePoint[current_x][current_y-1]);
}
//右
if(checkPosValid(current_x,current_y+1)){
System.out.print("右");
updatePoint(mazePoint[current_x][current_y],
mazePoint[current_x][current_y+1]);
}
System.out.println("---------------");
}
/**
*检查该节点是否有效
*
*/
privatebooleancheckPosValid(intx,inty){
//检查x,y是否越界,并且当前节点不是墙
if((x>=0&&x&&(y>=0&&y&&(mazePoint[x][y].getValue()!
=1)){
//检查当前节点是否已在关闭队列中,假设存在,那么返回"false"
Iteratorit=closedQueue.iterator();
Pointpoint=null;
while(it.hasNext()){
if((point=it.next())!
=null){
if(point.getX()==x&&point.getY()==y)
returnfalse;
}
}
returntrue;
}
returnfalse;
}
/**
*更新当前节点
*/
privatevoidupdatePoint(PointlastPoint,PointcurrentPoint){
intlast_x=lastPoint.getX();
intlast_y=lastPoint.getY();
intcurrent_x=currentPoint.getX();
intcurrent_y=currentPoint.getY();
//起始节点到当前节点的距离
inttemp_g=GList[last_x][last_y]+1;
//当前节点到目的位置的距离
System.out.print("["+current_x+","+current_y+"]"
+mazePoint[current_x][current_y].getValue());
inttemp_h=getPointDistance(current_x,current_y,endPoint.getX(),
endPoint.getY());
System.out.println("到目的位置的距离:
"+temp_h);
//f(x)=g(x)+h(x)
inttemp_f=temp_g+temp_h;
System.out.println("f(x)=g(x)+h(x):
"+temp_f+"="+temp_g+"+"
+temp_h);
//如果当前节点在开启列表中不存在,那么:
置入开启列表,并且“设置〞
//1)起始节点到当前节点距离
//2)当前节点到目的节点的距离
//3)起始节点到目的节点距离
if(!
openQueue.contains(currentPoint)){
openQueue.offer(currentPoint);
currentPoint.setFather(lastPoint);
System.out.println("添加到开启列表:
"+currentPoint.getValue()+"["
+currentPoint.getX()+","+currentPoint.getY()+"]");
//起始节点到当前节点的距离
GList[current_x][current_y]=temp_g;
//当前节点到目的节点的距离
HList[current_x][current_y]=temp_h;
//f(x)=g(x)+h(x)
FList[current_x][current_y]=temp_f;
}else{
//如果当前节点在开启列表中存在,并且,
//从起始节点、经过上一节点到当前节点、至目的地的距离<上一次记录的从起始节点、到当前节点、至目的地的距离,
//那么:
“更新〞
//1)起始节点到当前节点距离
//2)当前节点到目的节点的距离
//3)起始节点到目的节点距离
if(temp_f//起始节点到当前节点的距离
GList[current_x][current_y]=temp_g;
//当前节点到目的位置的距离
HList[current_x][current_y]=temp_h;
//f(x)=g(x)+h(x)
FList[current_x][current_y]=temp_f;
//更新当前节点的父节点
currentPoint.setFather(lastPoint);
}
System.out.println("currentPoint:
"+currentPoint.getValue()+"["
+currentPoint.getX()+","+currentPoint.getY()+"]");
System.out.println("currentPoint.father:
"
+currentPoint.getFather().getValue()+"["
+currentPoint.getFather().getX()+","
+currentPoint.getFather().getY()+"]");
}
}
/**
*打印行走路径
*
*/
publicvoidprintPath(){
System.out.println("================开场打印行走路径【用8表示】================");
Pointfather_point=null;
int[][]result=newint[mazeArray.length][mazeArray[0].length];
for(inti=0;ifor(intj=0;jresult[i][j]=0;
}
}
intstep=0;
father_point=mazePoint[endPoint.getX()][endPoint.getY()];
while(father_point!
=null){
System.out.println("【father_point】"+father_point.getValue()+"["
+father_point.getX()+","+father_point.getY()+"]");
if(father_point.equals(startPoint))
result[father_point.getX()][father_point.getY()]=2;
elseif(father_point.equals(endPoint)){
result[father_point.getX()][father_point.getY()]=3;
step++;
}else{
result[father_point.getX()][father_point.getY()]=8;
step++;
}
father_point=father_point.getFather();
}
//打印行走步数
System.out.println("stepis:
"+step);
for(inti=0;ifor(intj=0;jSystem.out.print(result[i][j]+"");
}
System.out.println();
}
}
}
〔3〕实验结果及分析。
实验结果:
很好的完成了实验目的,并且成功给出了最短路径!
!
A*算法作为解决最优路径的一种高效算法,自从1968年诞生以来,得到了广泛的应用,而其的多种改良算法也在许多领域发挥着作用。
可以预见,在更优的算法发现以前,A*算法将会得到更广泛的应用,并会由于图论、人工智能、机器人技术、自动控制等多学科的融合而得到更大的开展。