AStar 搜索(A*) 寻路算法

这几天看了A*搜索的寻路算法,发现精华在于f = g + h,我觉得难点在于如何确定估价函数的h。

本段代码是迷宫找路。估价函数:h是用的曼哈顿距离

贴出自己的代码,分享一下。可以讨论

文章会附上:代码.rar和测试

javaeye:http://cozilla.javaeye.com/

 

Main入后类
 
   

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Date;
import java.util.Scanner;


public class Mainx{
public static void main(String [] argv) throws FileNotFoundException {

FileInputStream fs
= new FileInputStream( " D:\\work\\Astar\\src\\c.txt " );
Scanner s
= new Scanner(fs);
int n,m;
n
= s.nextInt();
m
= s.nextInt();
AStar ast
= new AStar(n,m,s);
Date t
= new Date();
int res = ast.run();
Long x
= ( new Date()).getTime() - t.getTime();
ast.printRace();
System.out.println(
" 消耗 " + res);
System.out.println(
" 运行时间 " + x + " 毫秒 " );

}
}

 

AStar
 
   
import java.util.PriorityQueue;
import java.util.Scanner;

public class AStar {
private int stepx[] = { 0 , 1 , 1 , 1 , 0 , - 1 , - 1 , - 1 }; // 第一个是上,顺时针
private int stepy[] = { 1 , 1 , 0 , - 1 , - 1 , - 1 , 0 , 1 }; // 第一个是上,顺时针
private int gvalue[] = { 10 , 14 , 10 , 14 , 10 , 14 , 10 , 14 };

private int n;
private int m;
private char map[][];
private Node mapNode[][];

public AStar( int n, int m, Scanner s) {
this .n = n;
this .m = m;
this .init(s);
}

public int run() {
NodeComparator cmp
= new NodeComparator();
PriorityQueue
< Node > open = new PriorityQueue < Node > (n * m, cmp);
int x, y;
int nxti, nxtj;
Node nxt;

mapNode[
0 ][ 0 ].setInbox( true );
mapNode[
0 ][ 0 ].g = 0 ;
mapNode[
0 ][ 0 ].f = mapNode[ 0 ][ 0 ].g + mapNode[ 0 ][ 0 ].h;
open.add(mapNode[
0 ][ 0 ]);
while ( ! open.isEmpty()) {
Node top
= open.poll(); // 获取并移除此队列的头,如果此队列为空,则返回 null。
top.setSteped( true );
// 如果终点在结束列表中,表示表示找到了最优解
if (mapNode[n - 1 ][m - 1 ].isSteped())
break ;
x
= top.i;
y
= top.j;
for ( int i = 0 ; i < 8 ; i ++ ) {
nxti
= x + stepx[i];
nxtj
= y + stepy[i];
if ( ! inRange(nxti, nxtj))
continue ;
if (map[nxti][nxtj] == ' x ' ) continue ;
nxt
= mapNode[nxti][nxtj];
int gg = top.g + gvalue[i];
if (gg < nxt.g) {
nxt.g
= gg;
nxt.f
= gg + nxt.h;
nxt.parent
= top;
}
if ( ! nxt.isInbox()){
nxt.setInbox(
true );
open.add(nxt);
// System.out.println("--> ("+nxt.i+", "+nxt.j+")");
}
}
}
return mapNode[n - 1 ][m - 1 ].f;
}

public void printRace(){
Node cur
= mapNode[n - 1 ][m - 1 ];
while ( ! cur.parent.equals(cur)){
// System.out.println("[ "+cur.i+", "+cur.j+"]");
map[cur.i][cur.j] = ' O ' ;
cur
= cur.parent;
}

for ( int i = 0 ; i < n; i ++ ){
for ( int j = 0 ; j < m; j ++ ){
System.out.print(map[i][j]);
}
System.out.println();
}
}
private boolean inRange( int nxti, int nxtj) {
if (nxti >= n || nxtj >= m || nxti < 0 || nxtj < 0 )
return false ;
return true ;
}

private void init(Scanner s) {
map
= new char [n][m];
mapNode
= new Node[n][m];
for ( int i = 0 ; i < n; i ++ ) {
String tmp
= s.next();
for ( int j = 0 ; j < m; j ++ ) {
map[i][j]
= tmp.charAt(j);
mapNode[i][j]
= new Node(i, j);
mapNode[i][j].h
= getH(i + 1 , j + 1 );
}
}
}

/**
* 曼哈顿距离
*
*
@param i
*
@param j
*
@return
*/
private int getH( int i, int j) {
return (n - i + m - j) * 10 ;
}

public int getN() {
return n;
}

public void setN( int n) {
this .n = n;
}

public int getM() {
return m;
}

public void setM( int m) {
this .m = m;
}

public char [][] getMap() {
return map;
}

public void setMap( char [][] map) {
this .map = map;
}

}

 

Node
 
   

/**
* 地图中的每个位置
*
@author coolgo
*/
public class Node {

public int i,j;
/**
* f = g + h; h为估价函数
*/
public int f = 1 << 30 ;
public int g = 1 << 30 ;
public int h = 1 << 30 ;
/**
* if steped= true;表示已经在close列表中
*/
private boolean steped = false ;
/**
* if inbox = true;表示已经在open列表中
*/
private boolean inbox = false ;
public Node parent = this ;

public Node( int ii, int jj){
i
= ii;
j
= jj;
}

public void setSteped( boolean steped) {
this .steped = steped;
}

public boolean isSteped() {
return steped;
}

public void setInbox( boolean inbox) {
this .inbox = inbox;
}

public boolean isInbox() {
return inbox;
}
}

 

NodeComparator
 
   
import java.util.Comparator;

/**
* 比较器
*
@author coolgo
*/
public class NodeComparator implements Comparator < Node > {
@Override
public int compare(Node x, Node y) {
return x.f - y.f;
}
}

 

 
  
测试数据:
18 48
.x...........................x..................
.xxx...x........xxxxx...xxx..xxxxx..............
...x..xxxxx...xxx...xx..x...xx......xxxxxxx.....
...x......x...x......x..x....x......x.....xxxxxx
...xxxxx..x...x......x..x.......xx..x...........
.....x.x..x...x......xxxx........x..xxxxxxxxxx..
.....x.xxxxxx...........xx..xxxxxxxxxx..........
.....x......x...xx...xxxxxxxxx.......x..........
...xxxx.....x............x......xxx..x..xxxxxxxx
xx.......................xxxxxxxx....x...x......
....xxxxxxxxxxx..........x......x........x..x...
............xxxxxxxxx....x..x...x...xxxxxx..x...
xxxxxxxx....................x...........xx..x...
...............xxxxxxxxxxxxxxxxxxx..........x...
.xxxxxxxxxxxxxxx...........x....xxxxxxxxxxxxx...
.......x.....x......x......x....................
.......x.....x......x....xxxxxx........xxxxxxxxx
.........xxx........x......x....................

 
  
.x...........................x..................
Oxxx...x........xxxxx...xxx..xxxxx..............
.O.x..xxxxx...xxx...xx..x...xx......xxxxxxx.....
..Ox......x...x......x..x....x......x.....xxxxxx
..Oxxxxx..x...x......x..x.......xx..x...........
..O..x.x..x...x......xxxx........x..xxxxxxxxxx..
..O..x.xxxxxx...........xx..xxxxxxxxxx..........
..O..x......x...xx...xxxxxxxxx.......x..........
..Oxxxx.....x............x......xxx..x..xxxxxxxx
xx.OOOOOOOOOOOO..........xxxxxxxx....x...x..O...
....xxxxxxxxxxxOOOOOOOOO.x..OO..x........x.OxO..
............xxxxxxxxx...Ox.Ox.O.x...xxxxxx.OxO..
xxxxxxxx.................OO.x..OOO......xxO.xO..
...............xxxxxxxxxxxxxxxxxxxOOOOOOOO..xO..
.xxxxxxxxxxxxxxx...........x....xxxxxxxxxxxxxO..
.......x.....x......x......x...........OOOOOO...
.......x.....x......x....xxxxxx.......Oxxxxxxxxx
.........xxx........x......x...........OOOOOOOOO
消耗806
运行时间31毫秒

 

 

 

 

 

转载于:https://www.cnblogs.com/coolgo/archive/2010/12/02/1894119.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值