1 package cz.cuni.amis.utils.astar; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.HashMap; 6 import java.util.HashSet; 7 import java.util.List; 8 import java.util.Stack; 9 10 /** 11 * This class is returned by AStar.aStar(). 12 * It contains results from the search as well as method for 13 * finding 14 * the path from the startNode to the goalNode. 15 * 16 * It contains all data structures the AStar is using during the work. 17 * Everything is made public here so that AStar (during work) and you (for 18 * browsing the results) may use it. 19 * 20 * <p><p> 21 * Use amis-path-finding library instead, see svn://artemis.ms.mff.cuni.cz/pogamut/trunk/project/Utils/AmisPathFinding 22 */ 23 @Deprecated 24 public class AStarResult<NODE> { 25 26 /** 27 * Used by getPath() and filled by A* algorithm (AStar.aStar()). 28 * Keys are nodes and values are 'parent-nodes' (from where we've come to the key node 29 * on the path from startNode to key-node). 30 */ 31 public HashMap<NODE, NODE> previousNode = new HashMap<NODE, NODE>(); 32 33 /** 34 * List of nodes which is opened -> was touched by the algorithm and are 35 * subjects of examination. 36 * 37 * Initialized by AStar.aStar() 38 */ 39 public Collection<NODE> openList; 40 41 /** 42 * Nodes which were examined by the algoritm. 43 * At the end of work of AStar contains all the nodes which were examined. 44 * If AStar successful -> at least contains nodes on the shortest path from 45 * startNode to goalNode. 46 */ 47 public Collection<NODE> closeList = new HashSet<NODE>(); 48 49 /** 50 * Used and filled by A* algorithm (AStar.aStar()). 51 * Here we store the real cost from the startNode to the 'key'. 52 */ 53 public HashMap<NODE, Integer> pathCost = new HashMap<NODE, Integer>(); 54 55 /** 56 * Used and filled by A* alorithm (AStar.aStar()). 57 * Here we store estimated cost of the path from 'key' to the goal. 58 */ 59 public HashMap<NODE, Integer> estimatedCost = new HashMap<NODE, Integer>(); 60 61 /** 62 * Contains the number of iterations made by A* search. 63 * One iteration means evaluating of the one node ("touching" each of the neighbours) 64 * Is 0-based ... if startGoal == goalNode or startGoal then this will be 0. 65 */ 66 public long interations = 0; 67 68 /** 69 * Start node of the A*. 70 */ 71 public NODE startNode = null; 72 73 /** 74 * Node which was marked as a goalNode by AStarMap. (Note that you theoreticaly may have many 75 * goal nodes but A* searches only for the first one.) 76 * It's filled only if A* found the goalNoda! (success == true) 77 */ 78 public NODE goalNode = null; 79 80 /** 81 * Whether goalNode was found during the A* run. 82 * If this is true then goalNode is not null. 83 */ 84 public boolean success = false; 85 86 /** 87 * Used by getPath() to cache the path from startNode to goalNode once it has 88 * been found. 89 */ 90 private List<NODE> path = null; 91 92 /** 93 * Used by getPath() method when creating a list of nodes (the path) from startNode 94 * to goalNode. 95 * @param node 96 * @return previous node of supplied node | null 97 */ 98 public NODE getPreviousNode(NODE node){ 99 if (previousNode.containsKey(node)) return previousNode.get(node); 100 else return null; 101 } 102 103 /** 104 * Assing 'previous' as an previous node for 'node' (the path from 'startNode' to 'node' goes across 'previous'). 105 * @param node 106 * @param previous 107 */ 108 public void putPreviousNode(NODE node, NODE previous){ 109 previousNode.put(node, previous); 110 } 111 112 /** 113 * Returns cost of the path from startNode to node if the node was touched 114 * by A* algorithm (if A* was successful, then this always contains the goalNode 115 * and every node on the path). 116 * 117 * If node wasn't touched by A* algorithm, then it returns -1. 118 * 119 * @param node 120 * @return cost of the path from startNode to node 121 */ 122 public int getCostToNode(NODE node){ 123 if (pathCost.containsKey(node)) 124 return ((Integer)pathCost.get(node)).intValue(); 125 else 126 return -1; 127 } 128 129 /** 130 * Assing cost of the path from startNode to node. 131 * @param node 132 * @param cost 133 */ 134 public void putCostToNode(NODE node, Integer cost){ 135 pathCost.put(node, cost); 136 } 137 138 /** 139 * Returns estimated cost of the path from startNode to goal through node. 140 * If the node was touched by A* algorithm then it has this value stored here 141 * (if A* was successful, then this always contains the goalNode 142 * and every node on the path). 143 * 144 * If node wasn't touched by A* algorithm, then it returns -1. 145 * 146 * @param node 147 * @return cost of the path from startNode to node 148 */ 149 public int getEstimatedCostToNode(NODE node){ 150 if (estimatedCost.containsKey(node)) 151 return estimatedCost.get(node); 152 else 153 return -1; 154 } 155 156 /** 157 * Assing estimated cost of the path from startNode to goalNode through node. 158 * @param node 159 * @param cost 160 */ 161 public void putEstimatedCostToNode(NODE node, Integer cost){ 162 estimatedCost.put(node, cost); 163 } 164 165 /** 166 * Returns the path from startNode to goalNode. (Don't change it as it's cached, 167 * if you want to alter it - then copy it :-) 168 * 169 * First item is startNode and the last item is goalNode. 170 * If startNode == goalNode then it contains only one item. 171 * For each index ... path[index] has neighbour path[index+1]. 172 * 173 * If the path doesn't exist - returns null. 174 */ 175 public List<NODE> getPath(){ 176 if (path != null) 177 return path; 178 if (!success) 179 return null; 180 181 Stack<NODE> tempPath = new Stack<NODE>(); 182 tempPath.push(goalNode); 183 184 NODE node = goalNode; 185 while (node != startNode){ 186 node = getPreviousNode(node); 187 if (node == null) 188 return null; // path doesn't exist 189 tempPath.push(node); 190 } 191 192 path = new ArrayList<NODE>(); 193 194 while (!tempPath.empty()){ 195 path.add(tempPath.pop()); 196 } 197 198 return path; 199 } 200 201 /** 202 * If the AStar succeeded then it returns the distance to the goal. 203 * Returns -1 otherwise. 204 * @return distance | -1 205 */ 206 public int getDistanceToGoal(){ 207 if (!this.success) return -1; 208 return ((Integer) this.pathCost.get(goalNode)).intValue(); 209 } 210 }