** Heuristics for use in backtracking constraint-satisfaction search.
To choose a variable:
Choose the variable with the minimum remaining values ("MRV"
heuristic)
most constrained
we'll find out sooner if the current assignment is doomed to fail
In case of a tie, choose the variable that is involved in the most
constraints with other variables ("degree" heuristic)
Suppose a variable has been chosen.
Under the "least-constraining-value" heuristic for ordering values,
prefer the value that rules out the fewest choices for the neighboring
variables in the constraint graph.
**Chryparithmetic
Example to demonstrate setting up the problem, and the degree heuristic
In this cryptarithmetic problem, each letter stands for a different
number between 0 and 9. Representing this as a CSP:
two
two
-------
four
Variables: t, w, o, f, u, r, c1, c2, c3
The c* variables are the carries, numbered from the right.
The variable domains/values are all 0-9
[Actually, the carries may only be 0-1, but suppose we don't realize
this. If this were a less well-understood problem, we might not know
such value restrictions before searching.]
Constraints:
alldiff(t, w, o, f, u, r)
o + o = r + c1 * 10
w + w + c1 = u + c2 * 10
t + t + c2 = o + c3 * 10
f = c3
Assignment = {}
Choose next variable:
MRV, all ties
Break a tie with degree.
My proposal for a definition of the degree of variable V:
sum = 0
for all square boxes B connected to V in the constraint graph:
sum += number of edges of B - 1
degree(f) = 5 + 1 = 6
degree(c2) = 3 + 3 = 6
degree(w) = 5 + 3 = 8
degree(o) = 5 + 2 + 3 = 10
...
So, e.g., if o is in X constraints with variable V, we count
all X of them. Makes sense - each different constraint may
rule out additional values.
By degree, we choose o.
Now, we want to order the values (least constraining values). We
cannot compute this quickly in our heads.
Needed:
sums = {0:0,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0}
For i from 0 to 9:
plug "o=i" into the constraint formulas
For each neighbor "N" of "o" in the constraint graph:
sums[i] += the number of values remaining for "N"
Return the i such that sums[i] is the maximum value in sums
** Simple scheduling problem
Example to illustrate the entire (backtracking) search
procedure.
Lee, Wiebe, Litman, and Hwa teach at the same time. We need to assign
classrooms to them.
Note:
The constraint graph is fully connected.
The constraints are binary.
assignment = {}
Domain(Hwa) = (reading room, 5129, 5502, 5505, 6124)
Domain(Lee) = (reading room, 5129, 5502, 5505)
Domain(Wiebe) = (reading room, 5129)
Domain(Litman) = (reading room).
Let's go through the entire BACKTRACK process, using heuristcs,
forward checking, and arc consistency.
*BACKTRACK:
({},
Domain(Hwa) = (reading room, 5129, 5502, 5505, 6124)
Domain(Lee) = (reading room, 5129, 5502, 5505)
Domain(Wiebe) = (reading room, 5129)
Domain(Litman) = (reading room))
*Select variable (Minimum Value Remaining): Choose Litman
(Of course you would! Cuts down on the search immediately)
*Select value: there is only one, the reading room
*Inference 1: Forward checking
({Litman = reading room},
Domain(Hwa) = (5129, 5502, 5505, 6124)
Domain(Lee) = (5129, 5502, 5505)
Domain(Wiebe) = (5129))
*Inference 2: Arc Consistency
Queue:
Litman --> Hwa
Hwa --> Litman
Litman --> Lee
Lee --> Litman
Litman --> Wiebe
Wiebe --> Litman
Hwa --> Lee
Lee --> Hwa
Hwa --> Wiebe
Wiebe --> Hwa
Lee --> Wiebe
Wiebe --> Lee
Need to remove 5129 to make these arcs consistent:
Hwa --> Wiebe
Lee --> Wiebe
({Litman = reading room},
Domain(Hwa) = (5502, 5505, 6124)
Domain(Lee) = (5502, 5505)
Domain(Wiebe) = (5129))
Need to add to the queue:
Wiebe --> Hwa, Litman --> Hwa, Lee --> Hwa
Wiebe --> Lee, Litman --> Lee, Hwa --> Lee
All these are arc consistent.
Done with the INFERENCE step.
*BACKTRACK:
({Litman = reading room},
Domain(Hwa) = (5502, 5505, 6124)
Domain(Lee) = (5502, 5505)
Domain(Wiebe) = (5129))
* Select variable (Minimum Value Remaining): Choose Wiebe
* Select value: there is only one, 5129
*Inference 1: Forward checking
({Litman = reading room, Wiebe = 5129},
Domain(Hwa) = (5502, 5505, 6124)
Domain(Lee) = (5502, 5505))
*Inference 2: Arc Consistency
All of the arcs are consistent; no changes to domain
Done with the INFERENCE step.
* BACKTRACK
({Litman = reading room, Wiebe = 5129},
Domain(Hwa) = (5502, 5505, 6124)
Domain(Lee) = (5502, 5505))
*Select variable (Minimum Value Remaining): Choose Lee
*Select value: A tie; say, we choose 5502
*Inference 1: Forward checking
({Litman = reading room, Wiebe = 5129, Lee = 5502},
Domain(Hwa) = (5505, 6124))
*Inference 2: Arc Consistency
All of the arcs are consistent; no changes to domain.
** In the next step, we will succeed with either 5505 or 6124 assigned
to Hwa.
=== Now, let's motivate the value-ordering-heuristic. Suppose, for
the sake of illustration, we ignore the variable selection
heuristics, and happen to choose Lee for our first variable.
Domain(Hwa) = (reading room, 5129, 5502, 5505, 6124)
Domain(Wiebe) = (reading room, 5129)
Domain(Litman) = (reading room)
Domain(Lee) = (reading room, 5129, 5502, 5505)
assignment = {Lee=?}
The values of his domain are ordered: (5502 = 5505, 5129,reading room)
5502, 5505 each rules out 1; 5129 rules out 2; rr rules out 3
Suppose, we used the *opposite* heuristic, and we choose the MOST
constraining value, i.e., the one that rules out the MOST choices for
its neighbors (the reading room):
Domain(Hwa) = (5129, 5502, 5505, 6124)
Domain(Wiebe) = (5129)
Domain(Litman) = ()
assignment = {Lee=reading room}
Failure. We have to backtrack from here now; this was just wasted
work.
Suppose we choose the second most constraining value,
5129, and perform forward checking:
Domain(Hwa) = (reading room, 5502, 5505, 6124)
Domain(Wiebe) = (reading room)
Domain(Litman) = (reading room)
assignment = {Lee=5129}
The ARC Consistency process will discover that this is a failure
as well.
We want to minimize the number of "failure" paths we explore.
To do that, choose a value for Lee that leaves open more
possibilities for success.