summaryrefslogtreecommitdiffstats
path: root/src/bin/perfdhcp
diff options
context:
space:
mode:
authorSlawek Figiel <slawek@isc.org>2024-02-09 11:31:12 +0100
committerSlawek Figiel <slawek@isc.org>2024-02-20 09:33:35 +0100
commit2aa867b602f2869c697f30b4c43f2e1b30691e1a (patch)
tree1901cbb698925ec7104bc7698070debf3a8bc748 /src/bin/perfdhcp
parent[#2022] fix User-Password example in ARM (diff)
downloadkea-2aa867b602f2869c697f30b4c43f2e1b30691e1a.tar.xz
kea-2aa867b602f2869c697f30b4c43f2e1b30691e1a.zip
[#3207] Remove weighted random generator
Diffstat (limited to 'src/bin/perfdhcp')
-rw-r--r--src/bin/perfdhcp/random_number_generator.h112
-rw-r--r--src/bin/perfdhcp/tests/random_number_generator_unittest.cc222
2 files changed, 0 insertions, 334 deletions
diff --git a/src/bin/perfdhcp/random_number_generator.h b/src/bin/perfdhcp/random_number_generator.h
index c03e6aea16..eb4ddc0c36 100644
--- a/src/bin/perfdhcp/random_number_generator.h
+++ b/src/bin/perfdhcp/random_number_generator.h
@@ -84,118 +84,6 @@ private:
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > generator_; ///< Uniform generator
};
-/// \brief Weighted random integer generator
-///
-/// Generate random integers according different probabilities
-class WeightedRandomIntegerGenerator {
-public:
- /// \brief Constructor
- ///
- /// \param probabilities The probabilities for all the integers, the probability must be
- /// between 0 and 1.0, the sum of probabilities must be equal to 1.
- /// For example, if the probabilities contains the following values:
- /// 0.5 0.3 0.2, the 1st integer will be generated more frequently than the
- /// other integers and the probability is proportional to its value.
- /// \param min The minimum integer that generated, other integers will be
- /// min, min + 1, ..., min + probabilities.size() - 1
- WeightedRandomIntegerGenerator(const std::vector<double>& probabilities,
- size_t min = 0):
- dist_(0, 1.0), uniform_real_gen_(rng_, dist_), min_(min)
- {
- // The probabilities must be valid. Checking is quite an expensive
- // operation, so is only done in a debug build.
- areProbabilitiesValid(probabilities);
-
- // Calculate the partial sum of probabilities
- std::partial_sum(probabilities.begin(), probabilities.end(),
- std::back_inserter(cumulative_));
- // Init with the current time
- rng_.seed(time(NULL));
- }
-
- /// \brief Default constructor
- ///
- WeightedRandomIntegerGenerator():
- dist_(0, 1.0), uniform_real_gen_(rng_, dist_), min_(0)
- {
- }
-
- /// \brief Reset the probabilities
- ///
- /// Change the weights of each integers
- /// \param probabilities The probabilities for all the integers
- /// \param min The minimum integer that generated
- void reset(const std::vector<double>& probabilities, size_t min = 0)
- {
- // The probabilities must be valid.
- areProbabilitiesValid(probabilities);
-
- // Reset the cumulative sum
- cumulative_.clear();
-
- // Calculate the partial sum of probabilities
- std::partial_sum(probabilities.begin(), probabilities.end(),
- std::back_inserter(cumulative_));
-
- // Reset the minimum integer
- min_ = min;
- }
-
- /// \brief Generate weighted random integer
- size_t operator()()
- {
- return std::lower_bound(cumulative_.begin(), cumulative_.end(), uniform_real_gen_())
- - cumulative_.begin() + min_;
- }
-
-private:
- /// \brief Check the validation of probabilities vector
- ///
- /// The probability must be in range of [0, 1.0] and the sum must be equal
- /// to 1.0. Empty probabilities are also valid.
- ///
- /// Checking the probabilities is quite an expensive operation, so it is
- /// only done during a debug build (via a call through assert()). However,
- /// instead of letting assert() call abort(), if this method encounters an
- /// error, an exception is thrown. This makes unit testing somewhat easier.
- ///
- /// \param probabilities Vector of probabilities.
- /// \throw InvalidProbValue or SumNotOne when not valid.
- void areProbabilitiesValid(const std::vector<double>& probabilities) const
- {
- double sum = probabilities.empty() ? 1.0 : 0.0;
- for (const double it : probabilities) {
- //The probability must be in [0, 1.0]
- if (it < 0.0 || it > 1.0) {
- isc_throw(InvalidProbValue,
- "probability must be in the range 0..1");
- }
-
- sum += it;
- }
-
- double epsilon = 0.0001;
- // The sum must be equal to 1
- if (std::fabs(sum - 1.0) >= epsilon) {
- isc_throw(SumNotOne, "Sum of probabilities is not equal to 1");
- }
-
- return;
- }
-
- std::vector<double> cumulative_; ///< Partial sum of the probabilities
- boost::mt19937 rng_; ///< Mersenne Twister: A 623-dimensionally equidistributed uniform pseudo-random number generator
- boost::uniform_real<> dist_; ///< Uniformly distributed real numbers
-
- // Shortcut typedef
- // This typedef is placed directly before its use, as the sunstudio
- // compiler could not handle it being anywhere else (don't know why)
- typedef boost::variate_generator<boost::mt19937&, boost::uniform_real<> > UniformRealGenerator;
- UniformRealGenerator uniform_real_gen_; ///< Uniformly distributed random real numbers generator
-
- size_t min_; ///< The minimum integer that will be generated
-};
-
} // namespace perfdhcp
} // namespace isc
diff --git a/src/bin/perfdhcp/tests/random_number_generator_unittest.cc b/src/bin/perfdhcp/tests/random_number_generator_unittest.cc
index 58da95586b..613386062a 100644
--- a/src/bin/perfdhcp/tests/random_number_generator_unittest.cc
+++ b/src/bin/perfdhcp/tests/random_number_generator_unittest.cc
@@ -72,225 +72,3 @@ TEST_F(UniformRandomIntegerGeneratorTest, IntegerRange) {
// make sure the numbers are in range [min, max]
ASSERT_EQ(it - numbers.begin(), max() - min() + 1);
}
-
-/// \brief Test Fixture Class for weighted random number generator
-class WeightedRandomIntegerGeneratorTest : public ::testing::Test {
-public:
- WeightedRandomIntegerGeneratorTest()
- { }
-
- virtual ~WeightedRandomIntegerGeneratorTest()
- { }
-};
-
-// Test of the weighted random number generator constructor
-TEST_F(WeightedRandomIntegerGeneratorTest, Constructor) {
- vector<double> probabilities;
-
- // If no probabilities is provided, the smallest integer will always
- // be generated
- WeightedRandomIntegerGenerator gen(probabilities, 123);
- for (int i = 0; i < 100; ++i) {
- ASSERT_EQ(gen(), 123);
- }
-
-/// Some validation tests will incur performance penalty, so the tests are
-/// made only in "debug" version with assert(). But if NDEBUG is defined
-/// the tests will be failed since assert() is non-op in non-debug version.
-/// The "#ifndef NDEBUG" is added to make the tests be performed only in
-/// non-debug environment.
-#if !defined(NDEBUG)
- //The probability must be >= 0
- probabilities.push_back(-0.1);
- probabilities.push_back(1.1);
- ASSERT_THROW(WeightedRandomIntegerGenerator gen2(probabilities),
- InvalidProbValue);
-
- //The probability must be <= 1.0
- probabilities.clear();
- probabilities.push_back(0.1);
- probabilities.push_back(1.1);
- ASSERT_THROW(WeightedRandomIntegerGenerator gen3(probabilities),
- InvalidProbValue);
-
- //The sum must be equal to 1.0
- probabilities.clear();
- probabilities.push_back(0.2);
- probabilities.push_back(0.9);
- ASSERT_THROW(WeightedRandomIntegerGenerator gen4(probabilities), SumNotOne);
-
- //The sum must be equal to 1.0
- probabilities.clear();
- probabilities.push_back(0.3);
- probabilities.push_back(0.2);
- probabilities.push_back(0.1);
- ASSERT_THROW(WeightedRandomIntegerGenerator gen5(probabilities), SumNotOne);
-#endif
-}
-
-// Test the randomization of the generator
-TEST_F(WeightedRandomIntegerGeneratorTest, WeightedRandomization) {
- const int repeats = 100000;
- // We repeat the simulation for N=repeats times
- // for each probability p, its average is mu = N*p
- // variance sigma^2 = N * p * (1-p)
- // sigma = sqrt(N*2/9)
- // we should make sure that mu - 4sigma < count < mu + 4sigma
- // which means for 99.99366% of the time this should be true
- {
- double p = 0.5;
- vector<double> probabilities;
- probabilities.push_back(p);
- probabilities.push_back(p);
-
- // Uniformly generated integers
- WeightedRandomIntegerGenerator gen(probabilities);
- int c1 = 0;
- int c2 = 0;
- for (int i = 0; i < repeats; ++i){
- int n = gen();
- if (n == 0) {
- ++c1;
- } else if (n == 1) {
- ++c2;
- }
- }
- double mu = repeats * p;
- double sigma = sqrt(repeats * p * (1 - p));
- ASSERT_TRUE(fabs(c1 - mu) < 4*sigma);
- ASSERT_TRUE(fabs(c2 - mu) < 4*sigma);
- }
-
- {
- vector<double> probabilities;
- int c1 = 0;
- int c2 = 0;
- double p1 = 0.2;
- double p2 = 0.8;
- probabilities.push_back(p1);
- probabilities.push_back(p2);
- WeightedRandomIntegerGenerator gen(probabilities);
- for (int i = 0; i < repeats; ++i) {
- int n = gen();
- if (n == 0) {
- ++c1;
- } else if (n == 1) {
- ++c2;
- }
- }
- double mu1 = repeats * p1;
- double mu2 = repeats * p2;
- double sigma1 = sqrt(repeats * p1 * (1 - p1));
- double sigma2 = sqrt(repeats * p2 * (1 - p2));
- ASSERT_TRUE(fabs(c1 - mu1) < 4*sigma1);
- ASSERT_TRUE(fabs(c2 - mu2) < 4*sigma2);
- }
-
- {
- vector<double> probabilities;
- int c1 = 0;
- int c2 = 0;
- double p1 = 0.8;
- double p2 = 0.2;
- probabilities.push_back(p1);
- probabilities.push_back(p2);
- WeightedRandomIntegerGenerator gen(probabilities);
- for (int i = 0; i < repeats; ++i) {
- int n = gen();
- if (n == 0) {
- ++c1;
- } else if (n == 1) {
- ++c2;
- }
- }
- double mu1 = repeats * p1;
- double mu2 = repeats * p2;
- double sigma1 = sqrt(repeats * p1 * (1 - p1));
- double sigma2 = sqrt(repeats * p2 * (1 - p2));
- ASSERT_TRUE(fabs(c1 - mu1) < 4*sigma1);
- ASSERT_TRUE(fabs(c2 - mu2) < 4*sigma2);
- }
-
- {
- vector<double> probabilities;
- int c1 = 0;
- int c2 = 0;
- int c3 = 0;
- double p1 = 0.5;
- double p2 = 0.25;
- double p3 = 0.25;
- probabilities.push_back(p1);
- probabilities.push_back(p2);
- probabilities.push_back(p3);
- WeightedRandomIntegerGenerator gen(probabilities);
- for (int i = 0; i < repeats; ++i){
- int n = gen();
- if (n == 0) {
- ++c1;
- } else if (n == 1) {
- ++c2;
- } else if (n == 2) {
- ++c3;
- }
- }
- double mu1 = repeats * p1;
- double mu2 = repeats * p2;
- double mu3 = repeats * p3;
- double sigma1 = sqrt(repeats * p1 * (1 - p1));
- double sigma2 = sqrt(repeats * p2 * (1 - p2));
- double sigma3 = sqrt(repeats * p3 * (1 - p3));
- ASSERT_TRUE(fabs(c1 - mu1) < 4*sigma1);
- ASSERT_TRUE(fabs(c2 - mu2) < 4*sigma2);
- ASSERT_TRUE(fabs(c3 - mu3) < 4*sigma3);
- }
-}
-
-// Test the reset function of generator
-TEST_F(WeightedRandomIntegerGeneratorTest, ResetProbabilities) {
- const int repeats = 100000;
- vector<double> probabilities;
- int c1 = 0;
- int c2 = 0;
- double p1 = 0.8;
- double p2 = 0.2;
- probabilities.push_back(p1);
- probabilities.push_back(p2);
- WeightedRandomIntegerGenerator gen(probabilities);
- for (int i = 0; i < repeats; ++i) {
- int n = gen();
- if (n == 0) {
- ++c1;
- } else if (n == 1) {
- ++c2;
- }
- }
- double mu1 = repeats * p1;
- double mu2 = repeats * p2;
- double sigma1 = sqrt(repeats * p1 * (1 - p1));
- double sigma2 = sqrt(repeats * p2 * (1 - p2));
- ASSERT_TRUE(fabs(c1 - mu1) < 4*sigma1);
- ASSERT_TRUE(fabs(c2 - mu2) < 4*sigma2);
-
- // Reset the probabilities
- probabilities.clear();
- c1 = c2 = 0;
- p1 = 0.2;
- p2 = 0.8;
- probabilities.push_back(p1);
- probabilities.push_back(p2);
- gen.reset(probabilities);
- for (int i = 0; i < repeats; ++i) {
- int n = gen();
- if (n == 0) {
- ++c1;
- } else if (n == 1) {
- ++c2;
- }
- }
- mu1 = repeats * p1;
- mu2 = repeats * p2;
- sigma1 = sqrt(repeats * p1 * (1 - p1));
- sigma2 = sqrt(repeats * p2 * (1 - p2));
- ASSERT_TRUE(fabs(c1 - mu1) < 4*sigma1);
- ASSERT_TRUE(fabs(c2 - mu2) < 4*sigma2);
-}