2 import java
.io
.IOException
;
4 import java
.util
.LinkedList
;
5 import java
.util
.PriorityQueue
;
6 import java
.util
.Enumeration
;
10 * Denna klass implementerar olika sökalgoritmer för att hitta vägar
11 * mellan två platser på en karta.
13 public class MySearcher
extends MapSearcher
{
17 * Skapar en ny MySearcher-instans.
19 public MySearcher () {
24 * Specificerar kartan utifrån en fil i XML-format.
26 * @param map Den XML-fil som representerar kartan.
28 public void setMap(File mapFile
) {
30 List
<Element
> cityElements
;
32 doc
= loadXmlMap(mapFile
);
33 cityElements
= doc
.getRootElement().getChildren();
34 map
= new Graph(cityElements
.size(), 5);
36 // Iterate through cityElements
37 for (Element cityElement
: cityElements
) {
38 map
.insertNode(cityElement
.getAttributeValue("id"),
39 Integer
.parseInt(cityElement
.getAttributeValue("x")),
40 Integer
.parseInt(cityElement
.getAttributeValue("y")));
43 // Iterate through cityElements once more to add roads
44 for (Element cityElement
: cityElements
) {
45 GraphNode cityNode
= map
.getNode(cityElement
.getAttributeValue("id"));
47 // Iterate through roadElements in this cityElement
48 List
<Element
> roadElements
= cityElement
.getChildren();
49 for (Element roadElement
: roadElements
) {
50 GraphNode nodeAtEndOfRoad
= map
.getNode(roadElement
.getAttributeValue("to"));
51 Double distance
= Math
.hypot((cityNode
.getX() - nodeAtEndOfRoad
.getX()),
52 (cityNode
.getY() - nodeAtEndOfRoad
.getY()));
55 new Road(Integer
.parseInt(roadElement
.getAttributeValue("speed")),
57 map
.insertEdge(cityNode
.getName(),
58 nodeAtEndOfRoad
.getName(),
63 catch (IOException e
) {
64 System
.err
.println ("Could not read/find file.");
67 catch (JDOMException e
) {
68 System
.err
.println (e
.getMessage());
71 catch (NumberFormatException e
) {
72 System
.err
.println ("Coordinates cannot be parsed. Check XML-file for errors.");
78 * Utför sökning med Greedy Search.
80 * @param from Den plats sökningen börjar från.
81 * @param to Den plats sökningen avslutas på.
82 * @return En sträng som representerar vägen från start till mål.
84 public String
greedySearch (String from
, String to
) {
85 String pathToGoal
= "",
87 // 1. Set N to be a sorted list of initial nodes;
88 PriorityQueue
<GraphNode
> queue
=
89 new PriorityQueue
<GraphNode
>(this.map
.size());
90 // Set fromNodes distance to 0.0
91 map
.getNode(from
).setDistance(0.0);
92 queue
.add(map
.getNode(from
));
94 while (!queue
.isEmpty()) { // 2. If N is empty,
95 // 3. set n to be the first node in N, and remove n from N;
98 expandedNodes
+= n
.getName() + (n
== map
.getNode(to
) ?
"" : ", ");
100 // 4. If n is the goal node, exit and signal success;
101 if (n
== this.map
.getNode(to
)) {
102 pathToGoal
= n
.getName(); // Goal
105 while (n
!= map
.getNode(from
)) {
106 pathToGoal
= n
.getName() + ", " + pathToGoal
;
109 pathToGoal
= n
.getName() + ", " + pathToGoal
; // Beginning
110 System
.out
.println("\nAll expanded nodes:\n" + expandedNodes
+ "\n\n");
111 return "Path to goal:\n" + pathToGoal
+ "\n";
113 // 5. Otherwise add the children of n to N,
115 for (Enumeration
<GraphNode
> e
= n
.getNeighbours();
116 e
.hasMoreElements();) {
117 neighbour
= e
.nextElement();
118 neighbour
.setDistance(neighbour
.setDistanceToGoal(map
.getNode(to
)));
119 if (!neighbour
.isVisited() && !queue
.contains(neighbour
)) {
120 neighbour
.setParent(n
);
121 queue
.add(neighbour
);
123 // and return to step 2. (end of loop)
126 // 2. ... exit and signal failure
127 return "Goal not found!\n";
131 * Utför sökning med A*.
133 * @param from Den plats sökningen börjar från.
134 * @param to Den plats sökningen avslutas på.
135 * @param fastest Om <code>true</code>, hitta snabbaste vägen,
136 * annars den kortaste.
138 public String
aStar (String from
, String to
, boolean fastest
) {
139 String pathToGoal
= "",
141 // 1. Set N to be a sorted list of initial nodes;
142 PriorityQueue
<GraphNode
> queue
=
143 new PriorityQueue
<GraphNode
>(this.map
.size());
144 // Set fromNodes distance to 0.0
145 map
.getNode(from
).setDistance(0.0);
146 queue
.add(map
.getNode(from
));
148 while (!queue
.isEmpty()) { // 2. If N is empty,
149 // 3. set n to be the first node in N, and remove n from N;
152 expandedNodes
+= n
.getName() + (n
== map
.getNode(to
) ?
"" : ", ");
154 // 4. If n is the goal node, exit and signal success;
155 if (n
== this.map
.getNode(to
)) {
156 pathToGoal
= n
.getName(); // Goal
159 while (n
!= map
.getNode(from
)) {
160 pathToGoal
= n
.getName() + ", " + pathToGoal
;
163 pathToGoal
= n
.getName() + ", " + pathToGoal
; // Beginning
164 System
.out
.println("\nAll expanded nodes:\n" + expandedNodes
+ "\n\n");
165 return "Path to goal:\n" + pathToGoal
+ "\n";
167 // 5. Otherwise add the children of n to N,
169 for (Enumeration
<GraphNode
> e
= n
.getNeighbours();
170 e
.hasMoreElements();) {
171 neighbour
= e
.nextElement();
172 if (!neighbour
.isVisited()) {
174 neighbour
.setDistance(n
.getDistance()
175 + ((Road
) n
.getEdge(neighbour
)).getTravelTime()
176 + (neighbour
.setDistanceToGoal(map
.getNode(to
)) / (110/3.6) ));
179 neighbour
.setDistance(n
.getDistance()
180 + ((Road
) n
.getEdge(neighbour
)).getDistance()
181 + neighbour
.setDistanceToGoal(map
.getNode(to
)));
184 // sort the nodes in N according to the value on their
185 // evaluation function
186 else if (!queue
.contains(neighbour
)) {//&& !neighbour.isVisited()) {
187 neighbour
.setParent(n
);
188 queue
.add(neighbour
);
189 // and return to step 2. (end of loop)
193 System
.out
.println();
194 // 2. ... exit and signal failure
195 return "Goal not found!\n";
199 * Utför bredden-förstsökning.
201 * @param from Den plats sökningen börjar från.
202 * @param to Den plats sökningen avslutas på.
204 public String
breadthFirst (String from
, String to
) {
206 * Comments fetched from
207 * http://en.wikipedia.org/wiki/Breadth-first_search
208 * at Tue Oct 14 12:57:18 2008
210 LinkedList
<GraphNode
> queue
= new LinkedList
<GraphNode
>();
211 String expandedNodes
= "";
212 String pathToGoal
= "";
213 // 1. Put the root node on the queue.
214 queue
.add(map
.getNode(from
));
215 while (!queue
.isEmpty()) {
216 // 2. Pull a node from the beginning of the queue and examine it.
217 GraphNode n
= queue
.removeFirst();
219 expandedNodes
+= n
.getName() + (n
== map
.getNode(to
) ?
"" : ", ");
221 // * If the searched element is found in this node, quit
222 // * the search and return a result.
223 if (n
.getName().equals(to
)) {
224 pathToGoal
= n
.getName(); // Goal
227 while (n
!= map
.getNode(from
)) {
228 pathToGoal
= n
.getName() + ", " + pathToGoal
;
231 pathToGoal
= n
.getName() + ", " + pathToGoal
; // Beginning
232 System
.out
.println("\nAll expanded nodes:\n" + expandedNodes
+ "\n\n");
233 return "Path to goal:\n" + pathToGoal
+ "\n";
235 // * Otherwise push all the (so-far-unexamined) successors
236 // * (the direct child nodes) of this node into the end of
237 // * the queue, if there are any.
239 for (Enumeration e
= n
.getNeighbours(); e
.hasMoreElements();) {
240 GraphNode neighbour
= (GraphNode
) e
.nextElement();
241 if (!neighbour
.isVisited() && !queue
.contains(neighbour
)) {
242 neighbour
.setParent(n
);
243 queue
.add(neighbour
);
248 return "Goal not found!\n";
252 * Utför djupet-förstsökning.
254 * @param from Den plats sökningen börjar från.
255 * @param to Den plats sökningen avslutas på.
257 public String
depthFirst (String from
, String to
) {
258 LinkedList
<GraphNode
> stack
= new LinkedList
<GraphNode
>();
259 String expandedNodes
= "";
260 String pathToGoal
= "";
261 // 1. Push the root node onto the stack.
262 stack
.add(map
.getNode(from
));
263 while (!stack
.isEmpty()) {
264 // 2. Pop a node from the stack
265 GraphNode n
= stack
.removeLast();
266 // * Mark this node as visited
268 // * If the searched element is found in this node, quit
269 // * the search and return a result.
270 if (n
.getName().equals(to
)) {
271 expandedNodes
+= n
.getName();
272 pathToGoal
= n
.getName(); // Goal
275 while (n
!= map
.getNode(from
)) {
276 pathToGoal
= n
.getName() + ", " + pathToGoal
;
279 pathToGoal
= n
.getName() + ", " + pathToGoal
; // Beginning
280 System
.out
.println("\nAll expanded nodes:\n" + expandedNodes
+ "\n\n");
281 return "Path to goal:\n" + pathToGoal
+ "\n";
283 // * Otherwise push all the unvisited connecting nodes of n
285 for (Enumeration e
= n
.getNeighbours();
286 e
.hasMoreElements();) {
287 GraphNode neighbour
= (GraphNode
) e
.nextElement();
288 if (!neighbour
.isVisited() && !stack
.contains(neighbour
)) {
289 neighbour
.setParent(n
);
290 stack
.add(neighbour
);
294 expandedNodes
+= n
.getName() + ", ";
296 return "Goal not found!\n";
299 public String
toString() {
300 return map
.toString();