Measuring With Jugs A Solution in Finite Domain
Outline The Puzzle The Algorithm Introduction to Oz3 Implementation in Oz3
The Puzzle Given a set of jugs, and an unlimited supply of water, how would you measure out a quantity of water. Rules Unlimited Supply of water When a jug is poured into, it must be filled to capacity( unless there is not enough to fill it) Any jug may be emptied.
Example Given a 5 liter jug, a 3 liter jug, how do you measure out exactly 4 liters? Solution: Fill the 5 liter jug, empty it into the 3 liter jug leaving the 5 liter with 2 liters. Empty the 3 liter jug. Pour 2 liters from the 5 liter jug into the 3 liter jug. Fill the 5 liter jug. Pour 1 liter into the 3 liter jug to fill it. % liter jug now has 4 liters!
A Bit of History “Classic Mind Teaser” Puzzle was explored in “Measuring With Jugs” by Boldi, Santini and Vigna. In “Die Hard III”
The Algorithm This can be broken down fairly since the only important quantities are the capacities of the jugs and the final volume. So… Number of filling operations-Number of emptying operations=Final CapA*TimesA-CapB*TimesB=Final
Constraint Programming Constraint programming applies constraints given by the programmer to limit choices …
Intro to Oz variables -- a set of alphanumeric characters starting with a CAPITOL letter atoms -- set of alphanumeric characters beginning with a lower case letter (anAtom in Java would be "anAtom") keywords – declare, fun, Browse, Search
Other Neat Stuff Virtual string: a#b#C Virtual string: a#b#C Record: root(a b e o p) Record: root(a b e o p) List: [a 1 r B 24.6] List: [a 1 r B 24.6] Anonymous function: Anonymous function: fun{$ A B} ……. end fun{$ A B} ……. end
Oz Program declare declare fun{Factors Number} fun{Factors Number} fun{FactsIter Fact Number} fun{FactsIter Fact Number} if Fact == Number then [Fact] if Fact == Number then [Fact] elseif (Number mod Fact==0) then Fact|{FactsIter 2 (Number div Fact)} elseif (Number mod Fact==0) then Fact|{FactsIter 2 (Number div Fact)} else {FactsIter Fact+1 Number} else {FactsIter Fact+1 Number} end end in in {FactsIter 2 Number} {FactsIter 2 Number} end end {Browse {Factors 740}} {Browse {Factors 740}}
Constraint Programming Applied CapA*TimesA-CapA*TimesANeg Each jug is represented by a virtual string CapX#XTimesX#Conts show output explain output numbers
Numbers to Operations Introduction Structure of functions Code bits Final output
Overview Each jug is represented by a virtual string CapX#XTimesX#Conts Series of operations is represented by a List
Main Functions in JugsExten.oz DoSomething - all of the emptying and filling operations are performed in this function Combine2 – combines the contents of a list of jugs and writes a path that pours all into largest Combine -- combines all jugs into largest and writes a path WritePath -- Uses previous functions to Write a path describing all operations Jugs -- finite domain portion of program to find numbers
Bits Of Code -- Combine % Combines contents of all of the jugs into the largest fun{Combine Jugs} X List Total in {GCap Jugs List X _} Total={SumList3 X|List _} {Combine2 List X.1}|[to get Total] end
Output from Jugs7.oz CapA=6 CapB=10 CapC=15
JugsExten.oz Output
Conclusion This shows that Finite Domain Constraint Programming is useful for areas where it might not at first seem useful.