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_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);
|
BOOST_AUTO_TEST_CASE(makeRandom_should_use_every_possible_step_with_the_same_probability)
|
||||||
auto chromosome2 = Chromosome::makeRandom(numSteps);
|
{
|
||||||
BOOST_CHECK_EQUAL(chromosome1.length(), numSteps);
|
SimulationRNG::reset(1);
|
||||||
BOOST_CHECK_EQUAL(chromosome2.length(), numSteps);
|
constexpr int samplesPerStep = 100;
|
||||||
|
constexpr double relativeTolerance = 0.01;
|
||||||
|
|
||||||
multiset<string> steps1;
|
map<string, size_t> stepIndices = enumerateOptmisationSteps();
|
||||||
multiset<string> steps2;
|
auto chromosome = Chromosome::makeRandom(stepIndices.size() * samplesPerStep);
|
||||||
for (auto const& step: chromosome1.optimisationSteps())
|
|
||||||
steps1.insert(step);
|
|
||||||
for (auto const& step: chromosome2.optimisationSteps())
|
|
||||||
steps2.insert(step);
|
|
||||||
|
|
||||||
// Check if steps are different and also if they're not just a permutation of the same set.
|
vector<size_t> samples;
|
||||||
// Technically they could be the same and still random but the probability is infinitesimally low.
|
for (auto& step: chromosome.optimisationSteps())
|
||||||
BOOST_TEST(steps1 != steps2);
|
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)
|
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)
|
BOOST_FIXTURE_TEST_CASE(makeRandom_should_return_population_with_random_chromosomes, PopulationFixture)
|
||||||
{
|
{
|
||||||
auto population1 = Population::makeRandom(m_program, 100, 30, 30);
|
SimulationRNG::reset(1);
|
||||||
auto population2 = Population::makeRandom(m_program, 100, 30, 30);
|
constexpr int populationSize = 100;
|
||||||
|
constexpr int chromosomeLength = 30;
|
||||||
|
constexpr double relativeTolerance = 0.01;
|
||||||
|
|
||||||
BOOST_TEST(population1.individuals().size() == 100);
|
map<string, size_t> stepIndices = enumerateOptmisationSteps();
|
||||||
BOOST_TEST(population2.individuals().size() == 100);
|
auto population = Population::makeRandom(m_program, populationSize, chromosomeLength, chromosomeLength);
|
||||||
|
|
||||||
int numMatchingPositions = 0;
|
vector<size_t> samples;
|
||||||
for (size_t i = 0; i < 100; ++i)
|
for (auto& individual: population.individuals())
|
||||||
if (population1.individuals()[i].chromosome == population2.individuals()[i].chromosome)
|
for (auto& step: individual.chromosome.optimisationSteps())
|
||||||
++numMatchingPositions;
|
samples.push_back(stepIndices.at(step));
|
||||||
|
|
||||||
// Assume that the results are random if there are no more than 10 identical chromosomes on the
|
const double expectedValue = (stepIndices.size() - 1) / 2.0;
|
||||||
// same positions. One duplicate is very unlikely but still possible after billions of runs
|
const double variance = (stepIndices.size() * stepIndices.size() - 1) / 12.0;
|
||||||
// (especially for short chromosomes). For ten the probability is so small that we can ignore it.
|
|
||||||
BOOST_TEST(numMatchingPositions < 10);
|
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)
|
BOOST_FIXTURE_TEST_CASE(makeRandom_should_not_compute_fitness, PopulationFixture)
|
||||||
|
Loading…
Reference in New Issue
Block a user