Problem Solving as
State-Space Search
Lecture 2: Problem Solving Consider finite problems that can be represented in terms
of:
and Search • an initial state,
• one or more goal states, and
• a set of operators to transform the system from one state
ACSC 368 to another.
Solving the problem may correspond to:
Harris Papadopoulos •either reaching a goal state,
•or finding the best (or at least an acceptable) sequence of
operations to reach a goal state.
The Wolf, Goat and Cabbage The Wolf, Goat and Cabbage
Problem Problem (cont.)
A farmer and his wolf, goat, and cabbage come to • Initial State: Wolf, goat, cabbage and farmer
the north side of a river that they wish to cross. are on the north side of the river.
There is a boat, but it has only room for two, and the • Goal State: Wolf, goat, cabbage and farmer
farmer is the only one that can row. If the goat and are on the south side of the river.
the cabbage are left alone together, the goat will eat
• Operators: Farmer can move one thing at a
the cabbage. Similarly, if the wolf and the goat are
time across the river in the boat,
together without the farmer, the goat will be eaten.
or he can cross alone. But the
Devise a series of crossings of the river so that all
goat cannot be left alone with the
concerned make it across safely.
cabbage or with the wolf.
Prolog Representation of WGC Prolog Representation of WGC
initial(([f, w, g, c], [])). % move of w, or g, or c, and not f
move(A, B, A, B).
final(([], [f, w, g, c])).
move(A, B, A1, [M|B]) :- select(M, A, A1).
% operators of the form:
% next_state(State, NewState) % when is a side of the river safe if the farmer is not there?
next_state(([f|N], S), (N1, [f|S1])) :- safe([g]).
move(N, S, N1, S1), safe(N1). safe(L) :- not(member(g, L)).
next_state((N, [f|S]), ([f|N1], S1)) :-
move(S, N, S1, N1), safe(S1).
1
Blind Search Depth-First Search
1 In
Systematic exploration of a search tree, making no
use of knowledge about the particular problem.
2 A B C
Depth-first search: Search used by the Prolog
interpreter. Simple to implement, but may get stuck
in an infinite branch and fail to find a goal state in 3 D 4 E F Go H J
another branch. May not find shortest route to goal.
Breadth-first search: Visit all states at one level 5 K 8 Go L M N O P
before moving on to the next. Will inevitably find a
shortest route to a goal state, but requires a large
amount of memory. 6 Q 7 R S T U V
Depth-First Search Algorithm Depth-First Search Algorithm
To extend a path into an answer-path do To extend a path into an answer-path do
if the path has reached a goal state if the path has reached a goal state
then return it as an answer-path then return it as an answer-path
else if the current path can be extended to a new state else if the current path can be extended to a new state
then save the current state and continue then save the current state and continue
to extend the path from the new state to extend the path from the new state
else backtrack to extend the path from the else backtrack to extend the path from the
previous state to a different child previous state to a different child
To extend the path into a new state do To extend the path into a new state do
find another state which can be reached from the last find another state which can be reached from the last
state in the path; the state found is the new state state in the path and which does not already occur in
the path; the state found is the new state
Depth-First Search in Prolog Breadth-First Search
1 In
depth_first_search(AnsPath) :-
initial(Init), depth_first([Init], AnsPath).
2 A 3 B 4 C
depth_first([S|Path], [S]) :- final(S), !.
depth_first([S|Path], [S|AnsPath]) :-
5 D 6 E 7 F 8 Go H J
extend([S|Path], S1),
depth_first([S1, S|Path], AnsPath).
extend([S|Path], S1) :- K Go L M N O P
next_state(S, S1), not(member(S1, [S|Path])).
Q R S T U V
2
Breadth-First Search Algorithm Breadth-First Search Algorithm
(cont.)
To search for an answer-path do
create a queue containing a single path consisting of
the initial state, and apply the breadth-first procedure To expand a path in all possible ways and create a list of the
to expand this queue until an answer-path is found. resulting paths do
collect all paths S + path, where S is an extended state
To expand a queue do of path, into a list
if any path in the queue has reached a goal state
then return that path as an answer-path
else expand the first path of the queue in all possible
ways creating a list of the resulting paths, append the
list of extended paths to the end of the queue, remove
the first path from the queue, and continue to expand
the new queue
Breadth-First Search in Prolog Heuristic Search
breadth_first_search(AnsPath) :- The use of heuristics, based on knowledge of the problem,
initial(Init), breadth_first([[Init]], AnsPath). improves the efficiency of a search process by providing a
control strategy. Its effect is to prune the search tree.
breadth_first(PathQ, AnsPath) :-
member([S|RestP], PathQ), final(S), !, Heuristics are ‘rules of thumb’. They often provide a good
reverse([S|RestP], AnsPath). solution but not necessarily the best: they are approximations
and are not guaranteed to be right. They may even lead to a
breadth_first([Path|RestQ], AnsPath) :-
dead end.
expand(Path, NewPaths),
append(RestQ, NewPaths, PathQ), Heuristics may just be incorporated in operations (e.g. ‘In this
breadth_first(PathQ, AnsPath). state, such-and-such is likely to be a sensible action…’).
More usefully we calculate a heuristic evaluation function,
expand(Path, List) :- setof([S|Path], extend(Path, S), List), !.
which estimates the ‘value’ of a possible next state.
expand(Path, []). % in case setof fails: node has no successor
Evaluation Functions Hill-Climbing Search
Depth-First Search guided by an evaluation function
1 In (65)
An evaluation function maps a problem state to a numeric
value, which measures the ‘desirability’ of that state relative
to the problem to be solved; the smallest the value for a state, 2 A (28) B (29) C (48)
the more desirable it is.
Which aspects of the problem state are considered, how these
are evaluated, and how much weight is given to each one, are 3 D 4 E (32) F Go H (22) J (36)
chosen in such a way that the value of the function at a given (24) (13) (0)
node in the search tree gives as good an estimate as possible
of whether that node is on the path to a solution. (29) K 5 Go L M N (19) O P (12)
(0) (21) (33) (88)
Examples:
Chess: Material advantage of the player.
Route-finding: Distance from destination. Q R S T U V
(32) (24) (27) (6) (16) (35)
3
Hill-Climbing Search Algorithm Hill-Climbing Search in Prolog
To extend a path into an answer-path do hill_climb_search(AnsPath) :-
if the path has reached a goal state initial(Init), hill_climb([Init], AnsPath).
then return it as an answer-path
hill_climb([S|Path], [S]) :- final(S), !.
else if the current path can be extended to a new state
then save the current state and continue hill_climb([S|Path], [S|AnsPath]) :-
to extend the path from the best new state extend_best([S|Path], S1),
else backtrack to extend the path from the hill_climb([S1, S|Path], AnsPath).
previous state to the next best child
extend_best([S|Path], S1) :-
To extend the path into the best new state do best_next_state(S, S1), not(member(S1, [S|Path])).
create a list of all possible states which can be reached
best_next_state(S, S1) :-
from the last state in the path ordered in increasing
setof((V,NS), (next_state(S,NS), value(NS,V)), List),
value, and find the first state in this list which does not
member((V1, S1), List).
already occur in the path; this is the best new state
Best-First Search Best-First Search Algorithm
Breadth-First Search guided by an evaluation function
1 In (65)
To search for an answer-path do
start with a list containing just the initial state and
2 A (28) 4 B (29)
its value, and apply the best-first procedure to expand
C (48)
this path-list until an answer-path is found.
To expand a path-list with best-first search do
3 D (24) E
(32)
F 5 Go H (22) J (36) if the first path in the list has reached a goal state
(13) (0) then return that path as an answer-path
else expand the first path in the list in all possible
(29) K Go L M N (19) O P (12) ways, creating a list of the resulting paths ordered in
(0) (21) (33) (88) increasing value of the last state in each path, then
merge this list with the list of the remaining paths to
Q R S T U V get a new ordered list, and continue to expand the new
(32) (24) (27) (6) (16) (35) list
Best-First Search in Prolog Best-First Search in Prolog (cont.)
best_first_search(AnsPath) :- initial(Init), value(Init, V), merge([], L, L) :- !.
best_first([[V,Init]], AnsPath).
merge(L, [], L) :- !.
best_first([[_,S|Path]|_], AnsPath) :-
merge([H1|T1], [H2|T2], [H1|Rest]) :-
final(S), !, reverse([S|Path], AnsPath).
less(H1, H2), !, merge(T1, [H2|T2], Rest).
best_first([Path|Rest], AnsPath) :-
merge(L1, [H2|T2], [H2|Rest]) :-
expand(Path, NewPaths),
merge(L1, T2, Rest).
merge(NewPaths, Rest, NewList),
best_first(NewList, AnsPath). less([V1|Path1], [V2|Path2]) :- V1 < V2.
expand([_|Path], List) :-
setof([V,S|Path], (extend(Path,S), value(S,V)), List), !.
Note: The first element of each list that represents a path, is
expand(_, []). % in case setof fails: node has no successor the value of the last state in that path.
4
Cost Functions Best-Cost Search
Breadth-First Search guided by a cost function
A cost function gives a path from the initial to the current 1 In
state a numeric value. Normally one is looking for a path to 13 6
14
the goal state with the smallest possible value of the cost
function. 4 A 5 B 2 C
11 21 47 13
This can be used in heuristic search: 8 5
Best-cost search = breadth-first search + cost function 9 D 8 E F Go 3 H 6 J
Best-path search = breadth-first search + 18 9 31 1 22
4 15
cost function + evaluation function 10 Go N 7 O P
K L M
Examples:
4 20 11 18 28
Route-finding: Distance travelled. 5
Repairing a car: Time to reach given state of repair, or Q R S T U V
financial cost
Best-Cost Search in Prolog Best-Cost Search in Prolog (cont.)
best_cost_search(AnsPath) :- initial(Init), expand([C, S|Path], List) :-
best_cost([[0,Init]], AnsPath). setof([C1, S1, S|Path],
(extend([S|Path], S1), costsum(S, C, S1, C1)),
best_cost([[_,S|Path]|_], AnsPath) :-
List), !.
final(S), !, reverse([S|Path], AnsPath).
expand(_, []). % in case setof fails: node has no successor
best_cost([Path|Rest], AnsPath) :-
expand(Path, NewPaths), costsum(S, C, S1, C1) :-
merge(NewPaths, Rest, NewList), cost(S, S1, D), C1 is C + D.
best_cost(NewList, AnsPath).
Best-Path Search (A*) Best-Path Search in Prolog
Breadth-First Search guided by cost + evaluation functions
1 In (65)
best_path_search(AnsPath) :-
13 14 6 initial(Init), value(Init, V),
2 A (28) 3 B (29)
best_path([[V, V, Init]], AnsPath).
C (48)
11 21 47 13 best_path([[_, _, S|Path]|_], AnsPath) :-
8 5
6 final(S), !, reverse([S|Path], AnsPath).
5 D (24) (32) 4 F H (22) J (36)
E Go
best_path([Path|Rest], AnsPath) :-
18 9 (13) (0) 31 22
4 15 1 expand(Path, NewPaths),
(29) K merge(NewPaths, Rest, NewList),
7 Go L M N (19) O P (12)
best_path(NewList, AnsPath).
(0) (21) (33) (88)
4 20 11 5 18 28
Q R S T U V
(32) (24) (27) (6) (16) (35)
5
Best-Path Search in Prolog (cont.) Optimality of A*
The best-path, or A*, search algorithm uses a combined
expand([C, V, S|Path], List) :-
heuristic function as follows:
setof([C1, V1, S1, S|Path],
(extend([S|Path], S1), recost(S,C,V,S1,C1,V1)), For each node state n in the search tree, let
List), !. g(n) be the cost of reaching that node, i.e. the sum of the
costs of each step in the path to the node (exact), and
expand(_, []). % in case setof fails: node has no successor
h'(n) be the value of the evaluation function at node n
recost(S, C, V, S1, C1, V1) :- (estimate).
value(S1, V1), cost(S, S1, D),
Then A* search minimises the combined function ƒ(n) where,
C1 is C – V + D + V1.
ƒ(n) = g(n) + h'(n).
It turns out that if the evaluation function h'(n) satisfies
certain conditions, A* search is both complete and optimal.
Optimality of A* Developing Search Trees
Suppose the ‘real’ value of the evaluation function is h(n).
• To develop a search tree, start at the initial state
Then it can be proved that
and carry out the search algorithm, only adding
“if h'(n) ≤ h(n) for every state n, the A* algorithm will
never return a suboptimal path to the goal.”
states to the tree when they are reached by path
expansion under the algorithm.
Such an evaluation function, that never overestimates the cost • Do not include any repeated states on a given path
to reach the goal, is said to be an admissible heuristic.
through the tree. (States can of course be
Admissible heuristics are by nature optimistic, because they duplicated on different paths.)
think the cost of solving the problem is less than it actually is. • Stop the tree development, on a goal state, only
Explanation: Since g(n) is the exact cost to reach n, then if when the algorithm would finish (which is not
h'(n) is admissible we have as immediate consequence that necessarily the first goal state found).
ƒ(n) never overestimates the true cost of a solution through n.
Developing Search Trees for
Problem Characteristics
Heuristic Algorithms
The problem-solving approach may depend on the
• In the case of heuristic search algorithms, the characteristics of the problem in question:
developed tree illustrates how the algorithm in • Decomposable?
question prunes back the search tree.
• Recovery possible from bad steps?
• In order to develop the search tree of a given
heuristic algorithm based on breadth-first, you • Predictable universe?
need to create a table showing the path list • Obvious which is good solution?
considered by that algorithm at each point of time,
together with the list generated by the expansion • Is desired solution a state or a path?
of each path. The paths in the resulting lists should • Does solving the problem require a large amount of
also include their value and/or cost. knowledge?
• Human help needed?
6
Revision Exercise Adversary Search
Given the state-space graph:
(Game Playing)
(5)
A
5
D
Consider the simplest type of game:
2 4
(2) • Deterministic (non-probabilistic)
5
In B (4) 7 Go • Open (fully observable environment)
(9) (0)
3 6 • Two-player
C 4 E
(7) (4) • Turn-taking
Develop the search tree created by the best-path (A*) search • Zero-sum (equal and opposite utility functions of
algorithm, making clear the order in which states are players at the end of the game)
expanded.
Example Game – Placing Dominoes Placing Dominoes Game Tree
Each player places a domino in turn to cover exactly
Me
two squares, on a 3 by 3 board. One player (“Me”)
can place dominoes horizontally, and the other
player (“You”) can place dominoes vertically. The You
winner is the last one who will be able to place a
domino. -1 (You win)
Me
The tree for this game is shown in the next slide.
1 1 1 1 1 1 1 1
You
-1 -1
Minimax Search One-Ply Search
Most game search trees are too large to look at all
In
possible consequences of a move. So how well we
play will depend on how far ahead we look
(disregarding ‘higher’ knowledge based on pattern A B C
matching and recognition), and how well we (8) (3) (-2)
evaluate each possible state.
I would choose A.
Suppose we have an evaluation function applicable
to each state of play (e.g. material value in pieces of
chess). We can then choose the next move with the
highest value.
7
Two-Ply Search Minimax Value
In
Me
Maximise In backing up the values of the end nodes we assume
A B C that both players play optimally. So for our moves,
You we back up the highest values, whereas for the
Minimise
opponent’s moves, we back up the lowest values.
D E F G H J K
The resulting value of each state is called its
(9) (-6) (0) (0) (-2) (-4) (-3)
minimax value.
(n) is the value of the evaluation function for each state from
my viewpoint. Whereas I try to maximise the state as I see it,
you try to minimise it. So to decide which move to take
looking two steps ahead, I must back up the values.
In this case I would choose B as my next move.
Exercise - Three-Ply Search
Suppose I look three steps ahead:
In
Me
Maximise
A B C
You
Minimise
D E F G H J K
Me
Max.
L M N O P Q R S T U V W X Y
(8) (-2) (5) (3) (-10) (-2) (12) (4) (1) (-3) (3) (-5) (7) (2)
Now which move should I choose from In?