/* * AStar.java * * Created on April 1, 2007, 9:48 PM * */ package com.soulnew; /** *@author soulnew@soulnew.com */ import java.awt.Point; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import com.javaxyq.search.Searcher; public class AStar implements Searcher{ private int width; private int height; /** Creates a new instance of AStar */ public AStar() { } public static class PriorityList extends LinkedList { public void add(Comparable object) { for (int i = 0; i < size(); i++) { if (object.compareTo(get(i)) <= 0) { add(i, object); return; } } addLast(object); } } /** * Construct the path, not including the start node. */ protected List<AStarNode> constructPath(AStarNode node) { LinkedList<AStarNode> path = new LinkedList<AStarNode>(); while (node.pathParent != null) { path.addFirst(node); node = node.pathParent; } return path; } /** * ����������·�� * @param startNode * @param goalNode * @return */ public List<AStarNode> findPath(AStarNode startNode, AStarNode goalNode) { LinkedList openList = new LinkedList(); // Ҫ���ʵĽڵ�ŵ������ //LinkedList closedList = new LinkedList(); // �Ѿ����ʹ��Ľڵ�ŵ������ Set closedList = new HashSet(); // �Ѿ����ʹ��Ľڵ�ŵ������ startNode.costFromStart = 0; // ������㵽�Լ��ľ�����0 startNode.estimatedCostToGoal = startNode.getEstimatedCost(goalNode); // �õ����յ�Ĺ��Ƴɱ�,��ֵ����� startNode.pathParent = null; // �͹������һ��pathParent������¼,��һ���ڵ�,ͨ�������Ϳ����ҵ���� openList.add(startNode); // �������� �������������ı��� while (!openList.isEmpty()) { AStarNode node = (AStarNode) openList.removeFirst(); // ��Ҫ���ʵı���ȡ��һ���� // if (node == goalNode) { // construct the path from start to goal // �ҵ��յ���,ֹͣ����,��ʼ����·�� // } List neighbors = node.getNeighbors(); for (int i = 0; i < neighbors.size(); i++) { // �������е��ھӽڵ� AStarNode neighborNode = (AStarNode) neighbors.get(i); boolean isOpen = openList.contains(neighborNode); // isOpen �����ж��ھӽڵ��ڲ��ڼ������ʵı��� boolean isClosed = closedList.contains(neighborNode); // isClosed �����ж��ھӽڵ��ڲ����Ѿ����ʹ��ı��� int costFromStart = node.costFromStart + node.getCost(neighborNode); // ��øýڵ�ɱ� // check if the neighbor node has not been // traversed or if a shorter path to this // neighbor node is found. if ((!isOpen && !isClosed) || costFromStart < neighborNode.costFromStart) // ����ھӽڵ��Ƿ�δ����,���ҵ�������ھӽڵ�ĸ���·�� { neighborNode.pathParent = node; neighborNode.costFromStart = costFromStart; // neighborNode.estimatedCostToGoal = // neighborNode.getEstimatedCost(goalNode); // ���Ƶ��ص�ľ���ķ���,��ʹ��A*�ľ��峡�� if (node != goalNode) { if (isClosed) { closedList.remove(neighborNode); // �ҵ��ýڵ�ĸ���·��,���·�����ѷ��ʹ��ı������� } if (!isOpen) { openList.add(neighborNode); } } } } closedList.add(node); } return constructPath(goalNode); // no path found // return null; } public static void main(String[] args) { AStarNode nodeA = new AStarNode("A", 0, 10); AStarNode nodeB = new AStarNode("B", 5, 15); AStarNode nodeC = new AStarNode("C", 10, 20); AStarNode nodeD = new AStarNode("D", 15, 15); AStarNode nodeE = new AStarNode("E", 20, 10); AStarNode nodeF = new AStarNode("F", 15, 5); AStarNode nodeG = new AStarNode("G", 10, 0); AStarNode nodeH = new AStarNode("H", 5, 5); nodeA.neighbors.add(nodeF); nodeA.neighbors.add(nodeC); nodeA.neighbors.add(nodeE); nodeC.neighbors.add(nodeA); nodeC.neighbors.add(nodeE); nodeE.neighbors.add(nodeA); nodeE.neighbors.add(nodeC); nodeE.neighbors.add(nodeF); nodeF.neighbors.add(nodeA); nodeF.neighbors.add(nodeE); AStar bfs = new AStar(); System.out.println("From A to F: " + bfs.findPath(nodeA, nodeF).toString()); System.out.println("From C to F: " + bfs.findPath(nodeC, nodeF).toString()); System.out.println("From F to C: " + bfs.findPath(nodeF, nodeC)); // System.out.println("From A to G: " + // bfs.findPath(nodeH, nodeG).toString()); // System.out.println("From A to unknown: " + // bfs.findPath(nodeA, new AStarNode("unknown",0,0)).toString()); } /** * ��ʼ����� * @param maskdata ��ͼ��������(width*height) */ public void init(int width,int height,byte[] maskdata) { this.width = width; this.height = height; nodes = new AStarNode[width*height]; //��ʼ����� for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { //����ϵת�� if(maskdata[x+y*width]==0) { nodes[x+(height-y-1)*width] = new AStarNode(x, height-y-1); //�ж�8����ĵ��Ƿ񵽴� } } } //�ж�8����ĵ��Ƿ񵽴� for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { AStarNode node = getNode(x, y); if(node!=null ) { //�� �� AStarNode n = getNode(x-1, y); if(n!=null) { node.neighbors.add(n); } //�� �� n = getNode(x+1, y); if(n!=null) { node.neighbors.add(n); } //�� �� n = getNode(x, y-1); if(n!=null) { node.neighbors.add(n); } //�� �� n = getNode(x, y+1); if(n!=null) { node.neighbors.add(n); } //���� �I n = getNode(x-1, y-1); if(n!=null) { node.neighbors.add(n); } //���� �J n = getNode(x+1, y-1); if(n!=null) { node.neighbors.add(n); } //���� �K n = getNode(x+1, y+1); if(n!=null) { node.neighbors.add(n); } //���� �L n = getNode(x-1, y+1); if(n!=null) { node.neighbors.add(n); } } } } } private AStarNode[] nodes; /** * ��ȡij��ͨ�е� * @param x * @param y * @return */ public AStarNode getNode(int x,int y) { try { return nodes[x+y*width]; }catch(Exception e) { } return null; } /** * ��þ���õ�����Ŀ�ͨ�е� * @param x * @param y * @return */ public AStarNode getNearstNode(int x,int y) { AStarNode node = null; try { node = nodes[x+y*width]; while(node == null) { //TODO } }catch(Exception e) { } return node; } /** * �Ƿ����ͨ���õ� * @return */ public boolean pass(int x,int y) { return nodes[x+y*width] != null; } public List<Point> findPath(int x1,int y1,int x2,int y2){ AStarNode startNode = getNode(x1,y1); AStarNode goalNode = getNode(x2,y2); if(startNode==null || goalNode ==null) { return new ArrayList<Point>(); } List<AStarNode> nodepath = this.findPath(startNode, goalNode); List<Point> path = new ArrayList<Point>(nodepath.size()); for (AStarNode node : nodepath) { path.add(new Point(node.x, node.y)); } return path; } public int distance(List<Point> path){ int distance = 0; for(int i=0;i<path.size();i++){ Point p1 = (Point)path.get(i); AStarNode source = getNode(p1.x,p1.y); if(i<path.size()-1){ Point p2 = (Point)path.get(i+1); AStarNode destination = getNode(p2.x,p2.y); distance +=source.getDistance(destination); } } return distance; } public int linedistance(List<Point> path){ int distance = 0; for(int i=0;i<path.size();i++){ Point p1 = (Point)path.get(i); AStarNode source = new AStarNode(p1.x,p1.y); if(i<path.size()-1){ Point p2 = (Point)path.get(i+1); AStarNode destination = new AStarNode(p2.x,p2.y); distance +=source.getDistance(destination); } } return distance; } }