这几天看了A*搜索的寻路算法,发现精华在于f = g + h,我觉得难点在于如何确定估价函数的h。
本段代码是迷宫找路。估价函数:h是用的曼哈顿距离
贴出自己的代码,分享一下。可以讨论
文章会附上:代码.rar和测试
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;
}
}
/**
* 地图中的每个位置
* @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;
}
}
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;
}
}
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+"毫秒");
}
}
本文介绍了一种基于A*搜索算法的迷宫寻路实现方法。通过使用曼哈顿距离作为估价函数h,实现了从起点到终点的最短路径寻找。代码中详细展示了如何利用优先队列维护开放列表,并更新节点的g值与f值。
1317

被折叠的 条评论
为什么被折叠?



