AStar算法的学习

摘自:http://www.cnblogs.com/hxsyl/p/3994730.html

A*算法的java实现

import java.util.ArrayList;
import java.util.Collections;
import java.util.Stack;

/**
 * @author pang
 * 
 */
public class AStartPathFind {

	//前四个上下左右
	public final static int[] dx = { 0, -1, 0, 1, -1, -1, 1, 1 };
	public final static int[] dy = { -1, 0, 1, 0, 1, -1, -1, 1 };

	// 最外圈都是1表示不可通过
	final static public int[][] map = {
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Point start = new Point(1, 1);
		Point end = new Point(10, 13);
		/*
		 * 第一个问题:起点FGH需要初始化吗? 看参考资料的图片发现不需要
		 */
		Stack<Point> stack = printPath(start, end);
		if (null == stack) {
			System.out.println("不可达");
		} else {
			while (!stack.isEmpty()) {
				// 输出(1,2)这样的形势需要重写toString
				System.out.print(stack.pop() + " -> ");
			}
			System.out.println();
		}

	}

	public static Stack<Point> printPath(Point start, Point end) {

		/*
		 * 不用PriorityQueue是因为必须取出存在的元素
		 */
		ArrayList<Point> openTable = new ArrayList<Point>();
		ArrayList<Point> closeTable = new ArrayList<Point>();
		openTable.clear();
		closeTable.clear();
		Stack<Point> pathStack = new Stack<Point>();
		start.parent = null;
		// 该点起到转换作用,就是当前扩展点
		Point currentPoint = new Point(start.x, start.y);
		// closeTable.add(currentPoint);
		boolean flag = true;

		while (flag) {
			for (int i = 0; i < 8; i++) {
				int fx = currentPoint.x + dx[i];
				int fy = currentPoint.y + dy[i];
				Point tempPoint = new Point(fx, fy);
				if (map[fx][fy] == 1) {
					// 由于边界都是1中间障碍物也是1,,这样不必考虑越界和障碍点扩展问题
					// 如果不设置边界那么fx >=map.length &&fy>=map[0].length判断越界问题
					continue;
				} else {
					if (end.equals(tempPoint)) {
						flag = false;
						// 不是tempPoint,他俩都一样了此时
						end.parent = currentPoint;
						break;
					}
					if (i < 4) {
						tempPoint.G = currentPoint.G + 10;
					} else {
						tempPoint.G = currentPoint.G + 14;
					}
					tempPoint.H = Point.getDis(tempPoint, end);
					tempPoint.F = tempPoint.G + tempPoint.H;
					// 因为重写了equals方法,所以这里包含只是按equals相等包含
					// 这一点是使用java封装好类的关键
					if (openTable.contains(tempPoint)) {
						int pos = openTable.indexOf(tempPoint);
						Point temp = openTable.get(pos);
						if (temp.F > tempPoint.F) {
							openTable.remove(pos);
							openTable.add(tempPoint);
							tempPoint.parent = currentPoint;
						}
					} else if (closeTable.contains(tempPoint)) {
						int pos = closeTable.indexOf(tempPoint);
						Point temp = closeTable.get(pos);
						if (temp.F > tempPoint.F) {
							closeTable.remove(pos);
							openTable.add(tempPoint);
							tempPoint.parent = currentPoint;
						}
					} else {
						openTable.add(tempPoint);
						tempPoint.parent = currentPoint;
					}

				}
			}// end for

			if (openTable.isEmpty()) {
				return null;
			}// 无路径
			if (false == flag) {
				break;
			}// 找到路径
			openTable.remove(currentPoint);
			closeTable.add(currentPoint);
			Collections.sort(openTable);
			currentPoint = openTable.get(0);

		}// end while
		Point node = end;
		while (node.parent != null) {
			pathStack.push(node);
			node = node.parent;
		}
		return pathStack;
	}
}

class Point implements Comparable<Point> {
	int x;
	int y;
	Point parent;
	int F, G, H;

	public Point(int x, int y) {
		super();
		this.x = x;
		this.y = y;
		this.F = 0;
		this.G = 0;
		this.H = 0;
	}

	@Override
	public int compareTo(Point o) {
		// TODO Auto-generated method stub
		return this.F - o.F;
	}

	@Override
	public boolean equals(Object obj) {
		Point point = (Point) obj;
		if (point.x == this.x && point.y == this.y)
			return true;
		return false;
	}

	public static int getDis(Point p1, Point p2) {
		int dis = Math.abs(p1.x - p2.x) * 10 + Math.abs(p1.y - p2.y) * 10;
		return dis;
	}

	@Override
	public String toString() {
		return "(" + this.x + "," + this.y + ")";
	}

}

  

posted on 2016-06-15 17:28  huadoumi  阅读(519)  评论(0编辑  收藏  举报

导航