fun mapColoring space =
let
val nbColors = FD.range(space,(1,10))
val countries as #[au,ge,ne,sw,be,ita,po,fr,lu,sp] =
FD.rangeVec(space,10,(1,10))
(* borderTo gets a country and its neighbours and
ensures they do not have the same color *)
fun borderTo(space,c,nvec)=
Vector.app(fn x => FD.rel(space,c,FD.NQ,x))nvec
in
FD.branch(space,#[nbColors],FD.B_NONE,FD.B_MIN);
Vector.app(fn x => FD.rel(space,x,FD.LQ,nbColors))countries;
borderTo(space,au,#[ita,sw,ge]);
borderTo(space,be,#[fr,ne,ge,lu]);
borderTo(space,fr,#[sp,lu,ita]);
borderTo(space,ge,#[au,fr,lu,ne]);
borderTo(space,sp,#[po]);
borderTo(space,sw,#[ita,fr,ge,au]);
FD.branch(space,countries,FD.B_SIZE_MIN,FD.B_MIN);
{ netherlands = ne, belgium = be, france = fr, spain = sp,
portugal = po, germany = ge, luxemburg = lu, italy = ita,
switzerland = sw, austria = au, nbColors}
end
The search tree of mapColoring is interesting.First, colorings with 1, 2 and 3 colors are searched and not found. Then a coloring with 4 colors is searched. Now a solution is found quickly, without going through further failure nodes. There are many solutions using 4 colors since the particular color given to a country does not matter.
The statement
Explorer.exploreOne(mapColoring);results in the following solution:
{austria = intvar{|mathend000#1 | mathend000#}, belgium = intvar{| mathend000#2 | mathend000#}, france = intvar{| mathend000#1 | mathend000#},
germany = intvar{|mathend000#3 | mathend000#}, italy = intvar{| mathend000#3 | mathend000#}, luxemburg = intvar{| mathend000#4 | mathend000#},
nbColors = intvar{|mathend000#4 | mathend000#}, netherlands = intvar{| mathend000#1 | mathend000#}, portugal = intvar{| mathend000#1 | mathend000#},
spain = intvar{|mathend000#2 | mathend000#}, switzerland = intvar{| mathend000#2 | mathend000#}}
Guido Tack 2007-04-26