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...
#include <misc/modgray.hh>
Public Member Functions | |
loopless_modular_mixed_radix_gray_code (int n) | |
virtual | ~loopless_modular_mixed_radix_gray_code () |
iteration over an element in a tuple | |
virtual void | a_first (int j)=0 |
Reset aj to its initial value. | |
virtual void | a_next (int j)=0 |
Advance aj to its next value. | |
virtual bool | a_last (int j) const =0 |
Whether aj is on its last value. | |
iteration over all the tuples | |
void | first () |
Reset the iteration to the first tuple. | |
bool | last () const |
Whether this the last tuple. | |
bool | done () const |
Whether all tuple have been explored. | |
int | next () |
Update one item of the tuple and return its position. | |
Protected Attributes | |
int | n_ |
bool | done_ |
int * | a_ |
int * | f_ |
int * | m_ |
int * | s_ |
int * | non_one_radixes_ |
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 (a0,a1,...,an-1) where each aj range over a distinct set (this is the mixed radix part), so that only one aj changes between two successive tuples of the iteration (that is the Gray code part), and that this changes occurs always in the same direction, cycling over the set aj must cover (i.e., modular). The algorithm is loopless 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 aj, 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 aj at hand.
The class itself offers four functions to control the iteration over the set of all the (a0,a1,..., an-1) tuples: first(), next(), last(), and done(). These functions are usually used as follows:
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.)
spot::loopless_modular_mixed_radix_gray_code::loopless_modular_mixed_radix_gray_code | ( | int | n | ) |
Constructor.
n | The size of the tuples to enumerate. |
virtual spot::loopless_modular_mixed_radix_gray_code::~loopless_modular_mixed_radix_gray_code | ( | ) | [virtual] |
virtual void spot::loopless_modular_mixed_radix_gray_code::a_first | ( | int | j | ) | [pure virtual] |
Reset aj to its initial value.
virtual bool spot::loopless_modular_mixed_radix_gray_code::a_last | ( | int | j | ) | const [pure virtual] |
Whether aj is on its last value.
virtual void spot::loopless_modular_mixed_radix_gray_code::a_next | ( | int | j | ) | [pure virtual] |
Advance aj to its next value.
This will never be called if a_last(j) is true.
bool spot::loopless_modular_mixed_radix_gray_code::done | ( | ) | const [inline] |
Whether all tuple have been explored.
References done_.
void spot::loopless_modular_mixed_radix_gray_code::first | ( | ) |
bool spot::loopless_modular_mixed_radix_gray_code::last | ( | ) | const [inline] |
int spot::loopless_modular_mixed_radix_gray_code::next | ( | ) |
int* spot::loopless_modular_mixed_radix_gray_code::a_ [protected] |
bool spot::loopless_modular_mixed_radix_gray_code::done_ [protected] |
Referenced by done().
int* spot::loopless_modular_mixed_radix_gray_code::f_ [protected] |
Referenced by last().
int* spot::loopless_modular_mixed_radix_gray_code::m_ [protected] |
int spot::loopless_modular_mixed_radix_gray_code::n_ [protected] |
Referenced by last().
int* spot::loopless_modular_mixed_radix_gray_code::non_one_radixes_ [protected] |
int* spot::loopless_modular_mixed_radix_gray_code::s_ [protected] |