Informed Search (no corresponding text chapter)
Recall: Wanted " An algorithm and associated data structure(s) that can: 1) Solve an arbitrary 8-puzzle problem (or problem like it), 2) Do it in a reasonable amount of time and space-- efficiency, 3) Be guaranteed to first find the solution with the minimum number of actions--optimality.
Available Algorithms " Breadth-first state space search (BFS) ➢ Pro: optimal ➢ Con: memory inefficient " Depth-first state space search (DFS) ➢ Pro: memory efficient ➢ Con: non-optimal " Solution: A* search, a kind of "informed'' search
Informed and Uninformed Search " If a search algorithm makes an attempt to evaluate an item's children by comparing their "goodness'' with respect to the goal, it is informed. " If a search algorithm is not informed, it is uninformed or blind. " BFS and DFS are uninformed " Informed search requires the concept of an evaluation function
Evaluation Functions " An evaluation function takes a search space item as an argument and returns a numerical value as its "goodness'' " One type evaluates the strength of a state (as in chess playing programs)--the higher the better " Another type estimates the number of actions required to get to the goal. " Such an evaluation function is also called a "heuristic'' " The smaller an item's heuristic, the better
Heuristic for the 8-puzzle " If n is an item in the 8-puzzle state space, consider: ➢ h(n) = m, where m is the number of tiles out of place " h estimates, but does not overestimate, the number of actions required to get to the goal g " Note that h(g) = 0
8-puzzle Heuristic Function: Number of Misplaced Tiles up left down right left right up left right
Recall General Search Algorithm Suppose we added children to the waiting collection on the basis of their heuristic values. Q: What kind of collection should be used? search(root) returns Node or null { waiting.add(root) while (waiting is not empty) { node = waiting.remove() state = node.getState() if (problem.success(state)) return node else { children = expand(node) for each child in children waiting.add(child) } return null }
Priority Queues A (regular) queue has first-in, first-out (FIFO) behavior, where items must enter at the rear and leave from the front. In a priority queue items must leave from the front, but they enter on the basis of a priority (key) value. The queue is kept sorted by this value. Examples of priority queues: - CPU process queues - Print queues - Event-driven simulation (traffic flows) - VLSI design (channel routing, pin layout) - Artificial intelligence search algorithms
Implementations of Priority Queues Priority Queue Linked ListArrayBinary Heap Implemented as:
Array Implementation of Priority Queues Suppose items with keys 1, 3, 4, 7, 8, 9, 10, 14, 16 are to be stored in a priority queue. Array: A 1 NMax Suppose an item with key 2 is added: A 1 Max 2 Thus inserting takes O(N) time: linear
Linked List Implementation of Priority Queues L Suppose an item with key 15 is to be added: L 15 Only O(1) (constant) pointer changes required, but it takes O(N) pointer traversals to find the location for insertion.
Binary Heap Implementation of Priority Queues A binary heap is a "nearly full" binary tree: A binary heap has the property that, for every node other than a leaf, its key value is less than or equal to that of its children (called the Heap Property). Adds and removes: O(log 2 N) time (see java.util.PriorityQueue)
Example State Space With Heuristics Goal State
"Best-First'' State Space Search ● If the general search algorithm is used on a priority queue where the key value is a heuristic, it is called a "best-first'' search ● "Best-first'' search, despite its name, is not optimal
Trace of Best-First Search PQ: ( 1 ) PQ: ( ) PQ: ( 32 ) PQ: ( 32 ) PQ: ( 32 ) PQ: ( 32 ) These links are pointers back to parent created at expansion time
Notes On Best-First Search ● Solution path found in the example: – 1 4 10 17 18 28 ● Shortest possible solution: – 1 12 18 28 ● Therefore best-first search is not optimal ● The problem: the heuristic function rates state 4 better than state 5 ● Moral: heuristic functions are not perfect
Recall 8-puzzle Heuristic up left right up left right This state leads to the shortest solution This state may not lead to the shortest solution
Forcing an Optimal Solution In Previous Example ● The problem is that 18 is created as a result of expanding 17 instead of 12 ● 12 is preferred to 17 because it is shallower in the state space ● We can force 12 to precede 17 in the PQ by adding a state's depth to its heuristic value before adding it. ● When we order the PQ by key = heuristic + depth, then the search is called A*.
Taking Heuristics and Depth Into Account Goal State
A* Search PQ: ( )
Notes on A* Search ● Q: What is the solution path? – descended from ● A: 1 → 5 → 12 → 18 → 28 (optimal) ● If A* is used, and the heuristic never overestimates the number of moves required, a shortest solution is guaranteed (theorem). ● The number-of-misplaced-tiles heuristic never overestimates
BFS As A Special Case of A* ● Suppose the heuristic function is h(n) = 0 ● Then the priority queue key will be: ➢ h(n) + depth(n) = 0 + depth(n) = depth(n) ● If the children of an item at depth k are added to a priority queue they will go to the end (since they are at depth k+1) ● Therefore all items at depth k will be examined before items at depth k+1= the definition of BFS
Some Heuristics Are Better Than Others ● Although the number-of-misplaced-tiles heuristic never overestimates, we could do better without overestimating up left right This state is better because the 8 is closer to its destination. A more informed heuristic is the sum of the "Manhattan distances'' that the tiles are out of place
8-puzzle Heuristic Function: Sum of Manhattan Distances up left down right left right up left right
Comparing Heuristic Functions ● A heuristic h 1 is more informed than another heuristic h 2 if: – For all items n in the search space, h 1 (n) h 2 (n) The more informed the heuristic, the fewer items will be expanded If a heuristic is more informed without overestimating, then it is more efficient as well as optimal The sum-of-Manhattan-distances heuristic does not overestimate
Implementing Heuristics ● Need to add depth and heuristic to Node class as instance variables ● Abstract computeHeuristic(State) method can be added to Problem class; overridden in subclasses ● Depth and heuristic can be computed at expand time (depth of child = 1 + depth of parent) ● Use key = depth + heuristic to insert into priority queue