JAVA实现Astar寻径算法:
此算法的演示Applet程序请连接: http://www.dotnet.pp.ru/SMQ/AppletAstar.htm
此算法的主要公式:F=G+H
* G = 从起点,沿着产生的路径,移动到网格上指定方格的移动耗费。
* H = 从此点阵到结束点阵的预估移动耗费,这被称为开启式的。
* F = 等G+H的值,表示的一个权重值。
首先将开始点存入到开启列表当中(待检查的点),检查开始点,将周围的点阵的F,G,H值算出,将周围点阵加入到开启列表当中,将周围点阵的父节点指向当前查找的节点,然后将开启列表排序,查找到下一个最小的F值进行路径查找,以此类推,只到找结束点阵为止。
当路径查找到结束点时,就通过结束点在闭合列表当中查找它指向的父节点为路径加到路径列表当中,再通过查找的节点指向的父节点为路径加到路径列表当中,以此类推以找到父节点指各的是开始节点为止,此算法就结束。以上只是大概的讲解了一下Astar算法的原则。有兴趣可以到网上去查找资料,或者与我共同讨论和学习。我的QQ:565345652。
下面是我用JAVA实现的Astar的截图
 
 
 
 
JAVA 实现Astar的核心代码:
/*
* Astar算法实现的类
* */
package com.smq.astar;
public class AStarRule implements Runnable
{
private Testastar ta=null; //拿界面对象的一个引用
private boolean astar_ok=false; //Astar算法是否成功找到
private AstarObject minao; //开启列表查找的对象引用
/*
* 构造一个Astar算法
* */
public AStarRule(Testastar ta)
{
ta.setStart(System.currentTimeMillis());
this.ta=ta;
minao=ta.getStart_ao();
setAstar(ta.getStart_ao());
}
/*
* 运行Astar算法进行查找路径
* */
public void run()
{
System.out.println("astar");
while(!astar_ok)
{
System.out.println("astar");
if(ta.getOpenlistaos().size()==0)
{
astar_ok=true;
ta.setAstar_ok(true);
ta.getGb().setString("-还原-");
ta.setEnd(System.currentTimeMillis());
System.out.println("所用时间:"+(ta.getEnd()-ta.getStart())/1000.0);
}
System.out.println("open"+ta.getOpenlistaos().size());
System.out.println("close"+ta.getCloselistaos().size());
if(ta.getOpenlistaos().size()>=2)
{
Array();
for(int i=1;i<=4;i++)
{
this.LoadingOpenList(i);
minao.setOpenlist_ao(false);
minao.setCloselist_ao(true);
ta.getCloselistaos().add(minao);
ta.getOpenlistaos().remove(minao);
}
}else if(ta.getOpenlistaos().size()!=0)
{
minao=ta.getOpenlistaos().get(0);
for(int i=1;i&lt;=4;i++)
{
this.LoadingOpenList(i);
minao.setOpenlist_ao(false);
minao.setCloselist_ao(true);
ta.getCloselistaos().add(minao);
ta.getOpenlistaos().remove(minao);
}
}
try {
Thread.sleep(ta.getSpeed());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
* 排列开启列表
* */
public void Array()
{
AstarObject maxao;
minao=ta.getOpenlistaos().get(0);
for(int i=0;i&lt;ta.getOpenlistaos().size()-1;i++)
{
maxao=ta.getOpenlistaos().get(i);
if(minao.getAstarF()>=maxao.getAstarF())
{
minao=maxao;
}
}
}
/*
* 加入开启列表对象
* */
public void LoadingOpenList(int dir)
{
for(int i=0;i<ta.getAos().size();i++)
{
AstarObject ao=ta.getAos().get(i);
switch(dir)
{
case 1:
if(ao.getX()==minao.getX()+minao.getW()&&ao.getY()==minao.getY())
{
ao.setAstarG(minao.getAstarG()+10);
setAstar(ao);
ao.setCratelist_ao(false);
ao.setOpenlist_ao(true);
ao.setFathernode(minao);
ao.setFathernoad_x1(ao.getX()+ao.getW()/2);
ao.setFaternoad_y1(ao.getY()+ao.getH()/2);
ao.setFaternoad_x2(ao.getX()+2);
ao.setFaternoady2(ao.getY()+ao.getH()/2);
ta.getOpenlistaos().add(ao);
ta.getAos().remove(ao);
AstarObject upao=null,downao=null;
for(int n=0;n&lt;ta.getAos().size();n++)
{
AstarObject ao1=ta.getAos().get(n);
if(ao1.getX()==minao.getX()+ao1.getW()&&ao1.getY()==minao.getY()-ao1.getH())
{
upao=ao1;
}else if(ao1.getX()==minao.getX()+ao1.getW()&&ao1.getY()==minao.getY()+ao1.getH())
{
downao=ao1;
}
if(upao!=null&&downao!=null||n==ta.getAos().size()-1)
{
break;
}
}
if(upao!=null)
{
upao.setAstarG(minao.getAstarG()+14);
setAstar(upao);
upao.setCratelist_ao(false);
upao.setOpenlist_ao(true);
upao.setFathernode(minao);
upao.setFathernoad_x1(upao.getX()+upao.getW()/2);
upao.setFaternoad_y1(upao.getY()+upao.getH()/2);
upao.setFaternoad_x2(upao.getX()+2);
upao.setFaternoady2(upao.getY()+upao.getH()-2);
ta.getOpenlistaos().add(upao);
ta.getAos().remove(upao);
}else if(ta.isPath_ok())
{
this.lookupOpenlist(minao, minao.getX()+minao.getW(), minao.getY()-minao.getH(), 14, 2);
}
if(downao!=null)
{
downao.setAstarG(minao.getAstarG()+14);
setAstar(downao);
downao.setCratelist_ao(false);
downao.setOpenlist_ao(true);
downao.setFathernode(minao);
downao.setFathernoad_x1(downao.getX()+downao.getW()/2);
downao.setFaternoad_y1(downao.getY()+downao.getH()/2);
downao.setFaternoad_x2(downao.getX()+2);
downao.setFaternoady2(downao.getY()+2);
ta.getOpenlistaos().add(downao);
ta.getAos().remove(downao);
}else if(ta.isPath_ok())
{
this.lookupOpenlist(minao, minao.getX()+minao.getW(), minao.getY()+minao.getH(), 14, 3);
}
return;
}else if(ta.getEnd_ao().getX()==minao.getX()+minao.getW()&&ta.getEnd_ao().getY()==minao.getY())
{
this.astar_ok=true;
minao.setPathlist_ao(true);
ta.getPathlistaos().add(minao);
this.loadpathing(minao);
return;
}else if(i==ta.getAos().size()-1&&ta.isPath_ok())
{
this.lookupOpenlist(minao, minao.getX()+minao.getW(), minao.getY(), 10, 1);
this.lookupOpenlist(minao, minao.getX()+minao.getW(), minao.getY()-minao.getH(), 14, 2);
this.lookupOpenlist(minao, minao.getX()+minao.getW(), minao.getY()+minao.getH(), 14, 3);
return;
}
break;
case 2:
if(ao.getX()==minao.getX()&&ao.getY()==minao.getY()-minao.getH())
{
ao.setAstarG(minao.getAstarG()+10);
setAstar(ao);
ao.setCratelist_ao(false);
ao.setOpenlist_ao(true);
ao.setFathernode(minao);
ao.setFathernoad_x1(ao.getX()+ao.getW()/2);
ao.setFaternoad_y1(ao.getY()+ao.getH()/2);
ao.setFaternoad_x2(ao.getX()+ao.getW()/2);
ao.setFaternoady2(ao.getY()+ao.getH()-2);
ta.getOpenlistaos().add(ao);
ta.getAos().remove(ao);
AstarObject upao=null;
for(int n=0;n&lt;ta.getAos().size();n++)
{
AstarObject ao1=ta.getAos().get(n);
if(ao1.getX()==minao.getX()-ao1.getW()&&ao1.getY()==minao.getY()-ao1.getH())
{
upao=ao1;
}
if(upao!=null||n==ta.getAos().size()-1)
{
break;
}
}
if(upao!=null)
{
upao.setAstarG(minao.getAstarG()+14);
setAstar(upao);
upao.setCratelist_ao(false);
upao.setOpenlist_ao(true);
upao.setFathernode(minao);
upao.setFathernoad_x1(upao.getX()+upao.getW()/2);
upao.setFaternoad_y1(upao.getY()+upao.getH()/2);
upao.setFaternoad_x2(upao.getX()+upao.getW()-2);
upao.setFaternoady2(upao.getY()+upao.getH()-2);
ta.getOpenlistaos().add(upao);
ta.getAos().remove(upao);
}else if(ta.isPath_ok())
{
this.lookupOpenlist(minao, minao.getX()-minao.getW(), minao.getY()-minao.getH(), 14, 5);
}
return;
}else if(ta.getEnd_ao().getX()==minao.getX()&&ta.getEnd_ao().getY()==minao.getY()-minao.getH())
{
this.astar_ok=true;
minao.setPathlist_ao(true);
ta.getPathlistaos().add(minao);
this.loadpathing(minao);
return;
}else if(i==ta.getAos().size()-1&&ta.isPath_ok())
{
this.lookupOpenlist(minao, minao.getX(), minao.getY()-minao.getH(), 10, 4);
this.lookupOpenlist(minao, minao.getX()-minao.getW(), minao.getY()-minao.getH(), 14, 5);
return;
}
break;
case 3:
if(ao.getX()==minao.getX()-minao.getW()&&ao.getY()==minao.getY())
{
ao.setAstarG(minao.getAstarG()+10);
setAstar(ao);
ao.setCratelist_ao(false);
ao.setOpenlist_ao(true);
ao.setFathernode(minao);
ao.setFathernoad_x1(ao.getX()+ao.getW()/2);
ao.setFaternoad_y1(ao.getY()+ao.getH()/2);
ao.setFaternoad_x2(ao.getX()+ao.getW()-2);
ao.setFaternoady2(ao.getY()+ao.getH()/2);
ta.getOpenlistaos().add(ao);
ta.getAos().remove(ao);
AstarObject upao=null;
for(int n=0;n&lt;ta.getAos().size();n++)
{
AstarObject ao1=ta.getAos().get(n);
if(ao1.getX()==minao.getX()-ao1.getW()&&ao1.getY()==minao.getY()+ao1.getH())
{
upao=ao1;
}
if(upao!=null||n==ta.getAos().size()-1)
{
break;
}
}
if(upao!=null)
{
upao.setAstarG(minao.getAstarG()+14);
setAstar(upao);
upao.setCratelist_ao(false);
upao.setOpenlist_ao(true);
upao.setFathernode(minao);
upao.setFathernoad_x1(upao.getX()+upao.getW()/2);
upao.setFaternoad_y1(upao.getY()+upao.getH()/2);
upao.setFaternoad_x2(upao.getX()+upao.getW()-2);
upao.setFaternoady2(upao.getY()+2);
ta.getOpenlistaos().add(upao);
ta.getAos().remove(upao);
}else if(ta.isPath_ok())
{
this.lookupOpenlist(minao, minao.getX()-minao.getW(), minao.getY()+minao.getH(), 14, 7);
}
return;
}else if(ta.getEnd_ao().getX()==minao.getX()-minao.getW()&&ta.getEnd_ao().getY()==minao.getY())
{
this.astar_ok=true;
minao.setPathlist_ao(true);
ta.getPathlistaos().add(minao);
this.loadpathing(minao);
return;
}else if(i==ta.getAos().size()-1&&ta.isPath_ok())
{
this.lookupOpenlist(minao, minao.getX()-minao.getW(), minao.getY(), 10, 6);
this.lookupOpenlist(minao, minao.getX()-minao.getW(), minao.getY()+minao.getH(), 14, 7);
return;
}
break;
case 4:
if(ao.getX()==minao.getX()&&ao.getY()==minao.getY()+minao.getH())
{
ao.setAstarG(minao.getAstarG()+10);
setAstar(ao);
ao.setCratelist_ao(false);
ao.setOpenlist_ao(true);
ao.setFathernode(minao);
ao.setFathernoad_x1(ao.getX()+ao.getW()/2);
ao.setFaternoad_y1(ao.getY()+ao.getH()/2);
ao.setFaternoad_x2(ao.getX()+ao.getW()/2);
ao.setFaternoady2(ao.getY()+2);
ta.getOpenlistaos().add(ao);
ta.getAos().remove(ao);
return;
}else if(ta.getEnd_ao().getX()==minao.getX()&&ta.getEnd_ao().getY()==minao.getY()+minao.getH())
{
this.astar_ok=true;
minao.setPathlist_ao(true);
ta.getPathlistaos().add(minao);
this.loadpathing(minao);
return;
}else if(i==ta.getAos().size()-1&&ta.isPath_ok())
{
this.lookupOpenlist(minao, minao.getX(), minao.getY()+minao.getH(), 10, 8);
return;
}
break;
}
}
}
/*
* 算出点阵的F,G,H值
* */
public void setAstar(AstarObject ao)
{
if(ao.getX()&lt;ta.getEnd_ao().getX())
{
ao.setAstarH((ta.getEnd_ao().getX()-ao.getX())/ao.getW()*10);
}else if(ao.getX()>ta.getEnd_ao().getX())
{
ao.setAstarH((ao.getX()-ta.getEnd_ao().getX())/ao.getW()*10);
}
if(ao.getY()<ta.getEnd_ao().getY())
{
ao.setAstarH((ta.getEnd_ao().getY()-ao.getY())/ao.getH()*10+ao.getAstarH());
}else if(ao.getY()>ta.getEnd_ao().getY())
{
ao.setAstarH((ao.getY()-ta.getEnd_ao().getY())/ao.getH()*10+ao.getAstarH());
}
ao.setAstarF(ao.getAstarG()+ao.getAstarH());
}
/*
* 加载查找的最佳路径
* */
public void loadpathing(AstarObject ao)
{
System.out.println("loadpathaos"+ta.getPathlistaos().size());
for(int i=0;i&lt;ta.getCloselistaos().size();i++)
{
if(ao.getFathernode()==ta.getCloselistaos().get(i))
{
ta.getCloselistaos().get(i).setPathlist_ao(true);
ta.getPathlistaos().add(ta.getCloselistaos().get(i));
if(ta.getCloselistaos().get(i)!=ta.getStart_ao())
{
this.loadpathing(ta.getCloselistaos().get(i));
}else {
ta.setEnd(System.currentTimeMillis());
System.out.println("所用时间:"+(ta.getEnd()-ta.getStart())/1000.0);
ta.getGb().setString("-还原-");
ta.setAstar_ok(true);
}
return;
}
}
}
/*
* 查找开启列表当中的G值大小
* */
public void lookupOpenlist(AstarObject ao,int x,int y,int G,int dir)
{
for(int i=0;i&lt;ta.getOpenlistaos().size();i++)
{
AstarObject openlistao=ta.getOpenlistaos().get(i);
if(x==openlistao.getX()&&y==openlistao.getY())
{
if(ao.getAstarG()+G&lt;openlistao.getAstarG())
{
System.out.println("lookupOpenList_Ok");
openlistao.setAstarG(ao.getAstarG()+G);
openlistao.setAstarF(openlistao.getAstarG()+openlistao.getAstarH());
openlistao.setFathernode(ao);
switch(dir)
{
case 1:
openlistao.setFathernoad_x1(openlistao.getX()+openlistao.getW()/2);
openlistao.setFaternoad_y1(openlistao.getY()+openlistao.getH()/2);
openlistao.setFaternoad_x2(openlistao.getX()+2);
openlistao.setFaternoady2(openlistao.getY()+openlistao.getH()/2);
break;
case 2:
openlistao.setFathernoad_x1(openlistao.getX()+openlistao.getW()/2);
openlistao.setFaternoad_y1(openlistao.getY()+openlistao.getH()/2);
openlistao.setFaternoad_x2(openlistao.getX()+2);
openlistao.setFaternoady2(openlistao.getY()+openlistao.getH()-2);
break;
case 3:
openlistao.setFathernoad_x1(openlistao.getX()+openlistao.getW()/2);
openlistao.setFaternoad_y1(openlistao.getY()+openlistao.getH()/2);
openlistao.setFaternoad_x2(openlistao.getX()+2);
openlistao.setFaternoady2(openlistao.getY()+2);
break;
case 4:
openlistao.setFathernoad_x1(openlistao.getX()+openlistao.getW()/2);
openlistao.setFaternoad_y1(openlistao.getY()+openlistao.getH()/2);
openlistao.setFaternoad_x2(openlistao.getX()+openlistao.getW()/2);
openlistao.setFaternoady2(openlistao.getY()+openlistao.getH()-2);
break;
case 5:
openlistao.setFathernoad_x1(openlistao.getX()+openlistao.getW()/2);
openlistao.setFaternoad_y1(openlistao.getY()+openlistao.getH()/2);
openlistao.setFaternoad_x2(openlistao.getX()+openlistao.getW()-2);
openlistao.setFaternoady2(openlistao.getY()+openlistao.getH()-2);
break;
case 6:
openlistao.setFathernoad_x1(openlistao.getX()+openlistao.getW()/2);
openlistao.setFaternoad_y1(openlistao.getY()+openlistao.getH()/2);
openlistao.setFaternoad_x2(openlistao.getX()+openlistao.getW()-2);
openlistao.setFaternoady2(openlistao.getY()+openlistao.getH()/2);
break;
case 7:
openlistao.setFathernoad_x1(openlistao.getX()+openlistao.getW()/2);
openlistao.setFaternoad_y1(openlistao.getY()+openlistao.getH()/2);
openlistao.setFaternoad_x2(openlistao.getX()+openlistao.getW()-2);
openlistao.setFaternoady2(openlistao.getY()+2);
break;
case 8:
openlistao.setFathernoad_x1(openlistao.getX()+openlistao.getW()/2);
openlistao.setFaternoad_y1(openlistao.getY()+openlistao.getH()/2);
openlistao.setFaternoad_x2(openlistao.getX()+openlistao.getW()/2);
openlistao.setFaternoady2(openlistao.getY()+2);
break;
}
}
return;
}
}
}
}