forked from saschazar21/rushhour
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAStar.java
executable file
·96 lines (71 loc) · 2.79 KB
/
AStar.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package AStar;
import java.util.ArrayList;
import java.util.List;
import Heuristics.Heuristic;
/**
* This is the template for a class that performs A* search on a given rush hour
* puzzle with a given heuristic. The main search computation is carried out by
* the constructor for this class, which must be filled in. The solution (a path
* from the initial state to a goal state) is returned as an array of
* <tt>State</tt>s called <tt>path</tt> (where the first element
* <tt>path[0]</tt> is the initial state). If no solution is found, the
* <tt>path</tt> field should be set to <tt>null</tt>. You may also wish to
* return other information by adding additional fields to the class.
*/
public class AStar {
/** The solution path is stored here */
public State[] path;
private SortableList<HNode> open = new SortableList<HNode>();
private List<HNode> closed = new ArrayList<HNode>();
/**
* This is the constructor that performs A* search to compute a
* solution for the given puzzle using the given heuristic.
*/
public AStar(Puzzle puzzle, Heuristic heuristic) {
// Initialize root node w/ heuristics and path costs
int h = heuristic.getValue(puzzle.getInitNode().getState());
HNode root = new HNode(puzzle.getInitNode(), h);
// Add the root node to the open list
open.add(root);
while(!open.isEmpty()) {
// Only performs sort if list was changed
open.sort();
HNode current = open.remove(0);
if (current.getState().isGoal()) {
// Set the path array size to depth of goal state;
// The +1 should be necessary to also include root node.
path = new State[current.getDepth() + 1];
// Set the current node to pathNode
Node pathNode = current;
// Get state for every node and store it in the path array,
// then override current path node with its parent node until parent is null.
while (pathNode != null) {
path[pathNode.getDepth()] = pathNode.getState();
pathNode = pathNode.getParent();
}
// We found a solution, stop.
return;
}
closed.add(current);
for (Node successor : current.expand()) {
h = heuristic.getValue(successor.getState());
HNode hSuccessor = new HNode(successor, h);
if (open.contains(hSuccessor)) {
keepBetterNodeOnOpenList(hSuccessor);
} else if (!closed.contains(hSuccessor)) {
open.add(hSuccessor);
}
}
}
}
// Idea from: http://web.mit.edu/eranki/www/tutorials/search/
private void keepBetterNodeOnOpenList(HNode successor) {
HNode existing = open.get(successor);
if (existing != null) {
if (existing.compareTo(successor) > 0) {
open.remove(existing);
open.add(successor);
}
}
}
}