mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[yul-phaser] Population+Chromosome: Better tests for makeRandom()
This commit is contained in:
parent
806891f494
commit
823e715902
@ -67,25 +67,31 @@ BOOST_AUTO_TEST_CASE(constructor_should_convert_from_string_to_optimisation_step
|
||||
BOOST_TEST(Chromosome("ChrOmOsoMe").optimisationSteps() == expectedSteps);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(makeRandom_should_create_chromosome_with_random_optimisation_steps)
|
||||
BOOST_AUTO_TEST_CASE(makeRandom_should_return_different_chromosome_each_time)
|
||||
{
|
||||
constexpr uint32_t numSteps = 1000;
|
||||
SimulationRNG::reset(1);
|
||||
for (size_t i = 0; i < 10; ++i)
|
||||
BOOST_TEST(Chromosome::makeRandom(100) != Chromosome::makeRandom(100));
|
||||
}
|
||||
|
||||
auto chromosome1 = Chromosome::makeRandom(numSteps);
|
||||
auto chromosome2 = Chromosome::makeRandom(numSteps);
|
||||
BOOST_CHECK_EQUAL(chromosome1.length(), numSteps);
|
||||
BOOST_CHECK_EQUAL(chromosome2.length(), numSteps);
|
||||
BOOST_AUTO_TEST_CASE(makeRandom_should_use_every_possible_step_with_the_same_probability)
|
||||
{
|
||||
SimulationRNG::reset(1);
|
||||
constexpr int samplesPerStep = 100;
|
||||
constexpr double relativeTolerance = 0.01;
|
||||
|
||||
multiset<string> steps1;
|
||||
multiset<string> steps2;
|
||||
for (auto const& step: chromosome1.optimisationSteps())
|
||||
steps1.insert(step);
|
||||
for (auto const& step: chromosome2.optimisationSteps())
|
||||
steps2.insert(step);
|
||||
map<string, size_t> stepIndices = enumerateOptmisationSteps();
|
||||
auto chromosome = Chromosome::makeRandom(stepIndices.size() * samplesPerStep);
|
||||
|
||||
// Check if steps are different and also if they're not just a permutation of the same set.
|
||||
// Technically they could be the same and still random but the probability is infinitesimally low.
|
||||
BOOST_TEST(steps1 != steps2);
|
||||
vector<size_t> samples;
|
||||
for (auto& step: chromosome.optimisationSteps())
|
||||
samples.push_back(stepIndices.at(step));
|
||||
|
||||
const double expectedValue = (stepIndices.size() - 1) / 2.0;
|
||||
const double variance = (stepIndices.size() * stepIndices.size() - 1) / 12.0;
|
||||
|
||||
BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance);
|
||||
BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(constructor_should_store_optimisation_steps)
|
||||
|
@ -159,21 +159,24 @@ BOOST_FIXTURE_TEST_CASE(makeRandom_should_use_random_chromosome_length, Populati
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(makeRandom_should_return_population_with_random_chromosomes, PopulationFixture)
|
||||
{
|
||||
auto population1 = Population::makeRandom(m_program, 100, 30, 30);
|
||||
auto population2 = Population::makeRandom(m_program, 100, 30, 30);
|
||||
SimulationRNG::reset(1);
|
||||
constexpr int populationSize = 100;
|
||||
constexpr int chromosomeLength = 30;
|
||||
constexpr double relativeTolerance = 0.01;
|
||||
|
||||
BOOST_TEST(population1.individuals().size() == 100);
|
||||
BOOST_TEST(population2.individuals().size() == 100);
|
||||
map<string, size_t> stepIndices = enumerateOptmisationSteps();
|
||||
auto population = Population::makeRandom(m_program, populationSize, chromosomeLength, chromosomeLength);
|
||||
|
||||
int numMatchingPositions = 0;
|
||||
for (size_t i = 0; i < 100; ++i)
|
||||
if (population1.individuals()[i].chromosome == population2.individuals()[i].chromosome)
|
||||
++numMatchingPositions;
|
||||
vector<size_t> samples;
|
||||
for (auto& individual: population.individuals())
|
||||
for (auto& step: individual.chromosome.optimisationSteps())
|
||||
samples.push_back(stepIndices.at(step));
|
||||
|
||||
// Assume that the results are random if there are no more than 10 identical chromosomes on the
|
||||
// same positions. One duplicate is very unlikely but still possible after billions of runs
|
||||
// (especially for short chromosomes). For ten the probability is so small that we can ignore it.
|
||||
BOOST_TEST(numMatchingPositions < 10);
|
||||
const double expectedValue = (stepIndices.size() - 1) / 2.0;
|
||||
const double variance = (stepIndices.size() * stepIndices.size() - 1) / 12.0;
|
||||
|
||||
BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance);
|
||||
BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(makeRandom_should_not_compute_fitness, PopulationFixture)
|
||||
|
Loading…
Reference in New Issue
Block a user