package search; /** * A* Search implementation. * *Relies on implementation of an h() function *inside state to return a hueristic cost to the goal * * CS373 Assignment #1 * @author: Joey Kiernan and Nathaniel Lim * @version: 1.2 * @date: 2/19/10 */ import java.util.*; public class AStarSearch implements Search{ //This keeps track of the total cost //up to each node so far private Map<GraphNode, Integer> costs; public AStarSearch(){ costs = new HashMap<GraphNode, Integer>(); } /** *Takes a problem and a start configuration and solves for the goal state *using A* Search. *It will return a list of states (in reverse order) to the goal */ public List<State> pathSearch(ProblemGraph graph, String startStateString){ //frontier vector for keeping track of nodes to visit //We could think about making this a priorityQueue //to get log(n) complexity Vector<GraphNode> frontier = new Vector<GraphNode>(); GraphNode startNode = new GraphNode(graph.getState(startStateString)); frontier.add(startNode); costs.put(startNode, 0); //Very similar to BFS //in fact, if we had made Frontier a PriorityQueue //the code would have looked almost identical and finding //the minNode wouldn't be quite so expensive while(!frontier.isEmpty()){ //find the next step GraphNode minNode = frontier.get(0); for(GraphNode node : frontier){ if(pathCost(node) < pathCost(minNode)){ minNode = node; } } //take that step frontier.remove(minNode); if(minNode.getState().isGoal()){ return minNode.getPath(); } //expand Node List<GraphNode> children = minNode.getState().expandNode(); for(GraphNode childNode : children){ if(!costs.containsKey(childNode)){ childNode.setParent(minNode); frontier.add(childNode); //this assumes uniform cost costs.put(childNode, costs.get(minNode)+1); } } } return null; } /** *Returns the total estimated cost of taking any node *given the cost up to that node and that state's *hueristic function. */ private int pathCost(GraphNode node){ //should return cost(node) + hueristic return costs.get(node)+1 + node.getState().h(); } }