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 + ")";
	}

}

  

时间: 2024-10-20 15:03:14

AStar算法的学习的相关文章

算法导论学习---红黑树具体解释之插入(C语言实现)

前面我们学习二叉搜索树的时候发如今一些情况下其高度不是非常均匀,甚至有时候会退化成一条长链,所以我们引用一些"平衡"的二叉搜索树.红黑树就是一种"平衡"的二叉搜索树,它通过在每一个结点附加颜色位和路径上的一些约束条件能够保证在最坏的情况下基本动态集合操作的时间复杂度为O(nlgn).以下会总结红黑树的性质,然后分析红黑树的插入操作,并给出一份完整代码. 先给出红黑树的结点定义: #define RED 1 #define BLACK 0 ///红黑树结点定义,与普通

【算法导论学习-015】数组中选择第i小元素(Selection in expected linear time)

1.算法思想 问题描述:从数组array中找出第i小的元素(要求array中没有重复元素的情况),这是个经典的"线性时间选择(Selection in expected linear time)"问题. 思路:算法导论215页9.2 Selection in expect linear time 2.java实现 思路:算法导论216页伪代码 /*期望为线性时间的选择算法,输入要求,array中没有重复的元素*/ public static int randomizedSelect(i

算法的学习就像打副本

想连续几周每天都研究算法是不怎么现实的一件事情. 算法的学习就像打副本.网游大都是这样子的,团本每周都有固定的CD,每个团本有几个BOSS,相应的BOSS掉落固定的装备和材料等.首先,团本有周CD,若没有CD,可以天天打,不出2个月就打吐了,算法的学习也差不多,每周花个3到8小时来研究一下,刷刷题,也是比较好的一件事,若超过20小时在算法上,大脑也会抗拒的,因此不宜过多,掌握好节奏很重要.然后,每个BOSS都有相应的机制需要熟悉,算法也是这样,每道算法题都是有一点的技巧在里面的,你需要牢固掌握才

算法导论学习---红黑树详解之插入(C语言实现)

前面我们学习二叉搜索树的时候发现在一些情况下其高度不是很均匀,甚至有时候会退化成一条长链,所以我们引用一些"平衡"的二叉搜索树.红黑树就是一种"平衡"的二叉搜索树,它通过在每个结点附加颜色位和路径上的一些约束条件可以保证在最坏的情况下基本动态集合操作的时间复杂度为O(nlgn).下面会总结红黑树的性质,然后分析红黑树的插入操作,并给出一份完整代码. 先给出红黑树的结点定义: #define RED 1 #define BLACK 0 ///红黑树结点定义,与普通的二

算法导论 学习资源

学习的过程会遇到些问题,发现了一些比较好的资源,每章都会看下别人写的总结,自己太懒了,先记录下别人写的吧,呵呵. 1  Tanky Woo的,每次差不多都看他的 <算法导论>学习总结 - 1.前言 <算法导论>学习总结 - 2.第一章 && 第二章 && 第三章 <算法导论>学习总结 - 3.第四章 && 第五章 <算法导论>学习总结 - 4.第六章(1) 堆排序 <算法导论>学习总结 - 5.第六

【算法导论学习-014】计数排序(CountingSortTest)

参考:<算法导论>P194页 8.2节 Counting sort 1.Counting sort的条件 待排序数全部分布在0~k之间,且k是已知数:或者分布在min~max之间,等价于分布在0~max-min之间,max和min是已知数. 2.java 实现 /** * 创建时间:2014年8月17日 下午3:22:14 项目名称:Test * * @author Cao Yanfeng * @since JDK 1.6.0_21 类说明: 计数排序法,复杂度O(n), 条件:所有数分布在0

【算法导论学习-015】基数排序(Radix sort)

1.<算法导论>P197页 8.3节Radix sort 2.java实现 这里仅仅对[算法导论学习-014]计数排序 的参数进行了修改,同时仅仅修改了一行代码. /** * 创建时间:2014年8月17日 下午4:05:48 * 项目名称:Test * @author Cao Yanfeng * @since JDK 1.6.0_21 * 类说明: 利用计数排序实现基数排序 * 条件:待排序的所有数位数相同,注意,即便不相同,也可以认为是最多那个位数,如下面的例子可以认为都是3位数 */ p

关于统计变换(CT/MCT/RMCT)算法的学习和实现

原文地址http://blog.sina.com.cn/s/blog_684c8d630100turx.html 刚开会每周的例会,最讨厌开会了,不过为了能顺利毕业,只能忍了.闲话不多说了,下面把上周学习的一个简单的算法总结一下,以备后面写毕业论文的时候可以参考一下. 一.Census Transform(CT)算法的学习 Census Transform 算法是Ramin Zabih 和 John Woodfill 于1994年在他们的论文<Non-parametric LocalTransf

【算法导论学习-016】两个已排过序的等长数组的中位数(median of two sorted arrays)

问题来源 <算法导论>P223 9.3-8: Let X[1..n] and Y[1..n] be two arrays, each containing nnumbers already in sorted order. Give an O(lgn)-time algorithm to find themedian of all 2n elements in arrays X and Y. 翻译过来即:求两个等长(n个元素)的已排序数组A和B的中位数 方案1:对两个数组进行归并直到统计到第n