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 }