Loopless modular mixed radix Gray code iteration.This class is based on the loopless modular mixed radix gray code algorithm described in exercise 77 of "The Art of Computer
Programming", Pre-Fascicle 2A (Draft of section 7.2.1.1: generating all n-tuples) by Donald E. Knuth.
More...
Loopless modular mixed radix Gray code iteration.
This class is based on the loopless modular mixed radix gray code algorithm described in exercise 77 of "The Art of Computer
Programming", Pre-Fascicle 2A (Draft of section 7.2.1.1: generating all n-tuples) by Donald E. Knuth.
The idea is to enumerate the set of all n-tuples
(a<sub>0</sub>,a<sub>1</sub>,...,a<sub>n-1</sub>) where each
a<sub>j</sub> range over a distinct set (this is the <i>mixed
radix</i> part), so that only one a<sub>j</sub> changes between
two successive tuples of the iteration (that is the <i>Gray
code</i> part), and that this changes occurs always in the same
direction, cycling over the set a<sub>j</sub> must cover (i.e.,
<i>modular</i>). The algorithm is <i>loopless</i> in that
computing the next tuple done without any loop, i.e., in
constant time.
This class does not need to know the type of the a<sub>j</sub>,
it will handle them indirectly through three methods: a_first(),
a_next(), and a_last(). These methods need to be implemented
in a subclass for the particular type of a<sub>j</sub> at hand.
The class itself offers four functions to control the iteration
over the set of all the (a<sub>0</sub>,a<sub>1</sub>,...,
a<sub>n-1</sub>) tuples: first(), next(), last(), and done().
These functions are usually used as follows:
@code
for (g.first(); !g.done(); g.next()) use the tuple How to use the tuple of course depends on the way it as been stored in the subclass.
Finally, let's mention two differences between this algorithm and the one in Knuth's book. This version of the algorithm does not need to know the radixes (i.e., the size of set of each aj) beforehand: it will discover them on-the-fly when a_last(j) first return true. It will also work with aj that cannot be changed. (This is achieved by reindexing the elements through non_one_radixes_
, to consider only the elements with a non-singleton range.)