Browse Source

[2850] Add a way to pass a seed to the random number generator

Mukund Sivaraman 12 years ago
parent
commit
3599c07417

+ 7 - 2
src/lib/util/random/random_number_generator.h

@@ -60,7 +60,9 @@ public:
     ///
     /// \param min The minimum number in the range
     /// \param max The maximum number in the range
-    UniformRandomIntegerGenerator(int min, int max):
+    /// \param seed A seed for the RNG. If 0 is passed, the current time
+    /// is used.
+    UniformRandomIntegerGenerator(int min, int max, unsigned int seed = 0):
         min_(std::min(min, max)), max_(std::max(min, max)),
         dist_(min_, max_), generator_(rng_, dist_)
     {
@@ -73,7 +75,10 @@ public:
         }
 
         // Init with the current time
-        rng_.seed(time(NULL));
+        if (seed == 0) {
+            seed = time(NULL);
+        }
+        rng_.seed(seed);
     }
 
     /// \brief Generate uniformly distributed integer

+ 18 - 0
src/lib/util/tests/random_number_generator_unittest.cc

@@ -20,7 +20,10 @@
 #include <boost/shared_ptr.hpp>
 
 #include <iostream>
+#include <climits>
 
+#include <sys/types.h>
+#include <unistd.h>
 
 namespace isc {
 namespace util {
@@ -84,6 +87,21 @@ TEST_F(UniformRandomIntegerGeneratorTest, IntegerRange) {
     ASSERT_EQ(it - numbers.begin(), max() - min() + 1);
 }
 
+TEST_F(UniformRandomIntegerGeneratorTest, withSeed) {
+    // Test that two generators with the same seed return the same
+    // sequence.
+    UniformRandomIntegerGenerator gen1(0, INT_MAX, getpid());
+    vector<int> numbers;
+    for (int i = 0; i < 1024; ++i) {
+        numbers.push_back(gen1());
+    }
+
+    UniformRandomIntegerGenerator gen2(0, INT_MAX, getpid());
+    for (int i = 0; i < 1024; ++i) {
+        EXPECT_EQ(numbers[i], gen2());
+    }
+}
+
 /// \brief Test Fixture Class for weighted random number generator
 class WeightedRandomIntegerGeneratorTest : public ::testing::Test {
 public: