Fixes added Road.java
[ailab2.git] / src / MySearcher.java
blob6e0f08535f21662831f5dd2ff0b78cb42a7cc225
1 import java.io.File;
2 import java.io.IOException;
3 import java.util.List;
4 import java.util.LinkedList;
5 import java.util.PriorityQueue;
6 import java.util.Enumeration;
7 import org.jdom.*;
9 /**
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 {
14 private Graph map;
16 /**
17 * Skapar en ny MySearcher-instans.
19 public MySearcher () {
20 super ();
23 /**
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) {
29 Document doc;
30 List<Element> cityElements;
31 try {
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()));
54 Road road =
55 new Road(Integer.parseInt(roadElement.getAttributeValue("speed")),
56 distance);
57 map.insertEdge(cityNode.getName(),
58 nodeAtEndOfRoad.getName(),
59 road);
63 catch (IOException e) {
64 System.err.println ("Could not read/find file.");
65 System.exit(1);
67 catch (JDOMException e) {
68 System.err.println (e.getMessage());
69 System.exit(1);
71 catch (NumberFormatException e) {
72 System.err.println ("Coordinates cannot be parsed. Check XML-file for errors.");
73 System.exit(1);
77 /**
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 = "",
86 expandedNodes = "";
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));
93 GraphNode n;
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;
96 n = queue.poll();
97 // store expander
98 expandedNodes += n.getName() + (n == map.getNode(to) ? "" : ", ");
99 n.visit();
100 // 4. If n is the goal node, exit and signal success;
101 if (n == this.map.getNode(to)) {
102 pathToGoal = n.getName(); // Goal
103 n = n.getParent();
105 while (n != map.getNode(from)) {
106 pathToGoal = n.getName() + ", " + pathToGoal;
107 n = n.getParent();
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,
114 GraphNode neighbour;
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 = "",
140 expandedNodes = "";
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));
147 GraphNode n;
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;
150 n = queue.poll();
151 // store expander
152 expandedNodes += n.getName() + (n == map.getNode(to) ? "" : ", ");
153 n.visit();
154 // 4. If n is the goal node, exit and signal success;
155 if (n == this.map.getNode(to)) {
156 pathToGoal = n.getName(); // Goal
157 n = n.getParent();
159 while (n != map.getNode(from)) {
160 pathToGoal = n.getName() + ", " + pathToGoal;
161 n = n.getParent();
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,
168 GraphNode neighbour;
169 for (Enumeration<GraphNode> e = n.getNeighbours();
170 e.hasMoreElements();) {
171 neighbour = e.nextElement();
172 if (!neighbour.isVisited()) {
173 if (fastest) {
174 neighbour.setDistance(n.getDistance()
175 + ((Road) n.getEdge(neighbour)).getTravelTime()
176 + (neighbour.setDistanceToGoal(map.getNode(to)) / (110/3.6) ));
178 else {
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();
218 n.visit();
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
225 n = n.getParent();
227 while (n != map.getNode(from)) {
228 pathToGoal = n.getName() + ", " + pathToGoal;
229 n = n.getParent();
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.
238 else {
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
267 n.visit();
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
273 n = n.getParent();
275 while (n != map.getNode(from)) {
276 pathToGoal = n.getName() + ", " + pathToGoal;
277 n = n.getParent();
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
284 else {
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();