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毫秒

 

 

 

 

 

posted @ 2010-12-02 10:18  coolgo  阅读(849)  评论(0编辑  收藏  举报