Main Page   Class Hierarchy   Compound List   File List   Compound Members  

randomizer.h

00001 /****************************************************
00002  *  Bachelor Project:                               *
00003  *  External Memory Minimum Spanning Trees          *
00004  *  by Dominik Schultes <mail@dominik-schultes.de>  *
00005  *                                                  *
00006  *                randomizer.h                      *
00007  *                                                  *
00008  *  May 22, 2003                                    *
00009  ****************************************************/
00010 
00011 
00012 #ifndef RANDOMIZER_H
00013 #define RANDOMIZER_H
00014 
00018 class RandomizerLinearCongruence
00019 {
00020  public:
00026     RandomizerLinearCongruence(NodeCount noOfNodes)
00027         {determineNextPrime(noOfNodes);}
00028 
00030     NodeID operator()(NodeID nodeID) const {
00031         typedef unsigned long long int bigNumber;
00032         
00033         bigNumber x = nodeID;
00034         const bigNumber a = 321321;
00035         const bigNumber c = 1;
00036         bigNumber m = _prime;
00037 
00038         // the linear congruential method
00039         return (a * x + c) % m;
00040     }
00041     
00042  private:
00044     NodeCount _prime;
00045 
00047     void determineNextPrime(NodeCount noOfNodes) {
00048         NodeCount p;
00049         for (p = noOfNodes-1; ! isPrime(p); p++);
00050         _prime = p;
00051     }
00052 
00054     bool isPrime(NodeCount p) const {
00055         for (NodeCount i=2; i <= std::sqrt((double)p); i++) {
00056             if (p % i == 0) return false;
00057         }
00058         return true;
00059     }
00060 };
00061 
00062 
00066 class RandomizerFeistel
00067 {
00068  public:
00074     RandomizerFeistel(NodeCount noOfNodes) {
00075         // compute the next integer >= the square root of the given number of nodes
00076         _sqRoot = (NodeID)std::sqrt((double)noOfNodes);
00077         if ((NodeCount)_sqRoot * _sqRoot < noOfNodes) _sqRoot++;
00078         // initialize the table of random numbers (used by the Feistel permutations)
00079         initRandomNumbers();
00080     }
00081 
00083     NodeID operator()(NodeID nodeID) const {
00084         // Split the given number into two parts
00085         int a = nodeID / _sqRoot;
00086         int b = nodeID % _sqRoot;
00087 
00088         // Perform the Feistel permutations
00089         for (int i=0; i<_noOfIterations; i++) {
00090             int newA = b;
00091             b = a + randomNumbers[i][b];
00092             if (b >= _sqRoot) b -= _sqRoot; // mod _sqRoot
00093             a = newA;
00094         }
00095 
00096         // Recombine a and b to obtain the result
00097         return a * _sqRoot + b;
00098     }
00099         
00100  private:
00102     static const int _noOfIterations = 2;
00103     
00105     static const int _maxSqRoot = 0x10000;
00106 
00108     NodeID _sqRoot;
00109 
00111     int randomNumbers[_noOfIterations][_maxSqRoot];
00112 
00114     void initRandomNumbers() {
00115         for (int i=0; i<_noOfIterations; i++)
00116             for (int j=0; j<_maxSqRoot; j++) {
00117                 // each random number is an integer in {0,...,_sqRoot-1}
00118                 randomNumbers[i][j] = (int)(rand() / (double)(RAND_MAX+1.0) * _sqRoot);
00119             }
00120     }
00121 };
00122 
00123 
00130 template <typename Bijection = RandomizerLinearCongruence>
00131 class Randomizer
00132 {
00133  public:
00135     Randomizer(NodeCount noOfNodes)
00136         : _noOfNodes( noOfNodes ), _bijection( noOfNodes )
00137         {}
00138 
00145     RelabeledEdge randomize(const Edge &edge) const {
00146         return RelabeledEdge(randomize(edge.source()),randomize(edge.target()),
00147                              edge.weight(),edge.source(),edge.target());
00148     }
00149         
00150  private:
00152     NodeCount _noOfNodes;
00153 
00155     Bijection _bijection;
00156 
00158     NodeID randomize(NodeID nodeID) const {
00159         NodeID x = nodeID;
00160         
00161         // The application of the underlying bijection is repeated
00162         // until the result is in the correct co-domain.
00163         do {
00164             x = _bijection( x );
00165         } while (x >= _noOfNodes);
00166         
00167         return x;
00168     }
00169     
00170 };
00171 
00172 #endif // RANDOMIZER_H

Generated on Thu Aug 14 15:13:27 2003 for External Memory Minimum Spanning Trees by doxygen1.2.17