From d75f0ba437fea126fe32e438292b3e6885290894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 11 Sep 2020 20:49:25 +0200 Subject: [PATCH] [yul-phaser] Chromosome: Make it possible to use genes that do not correspond to existing optimiser steps --- test/yulPhaser/Chromosome.cpp | 9 +++++++++ tools/yulPhaser/Chromosome.cpp | 5 +++++ tools/yulPhaser/Chromosome.h | 3 +++ tools/yulPhaser/Mutations.cpp | 32 ++++++++++++++++---------------- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/test/yulPhaser/Chromosome.cpp b/test/yulPhaser/Chromosome.cpp index 509ad0036..fd457645a 100644 --- a/test/yulPhaser/Chromosome.cpp +++ b/test/yulPhaser/Chromosome.cpp @@ -120,6 +120,15 @@ BOOST_AUTO_TEST_CASE(constructor_should_allow_duplicate_steps) BOOST_TEST(Chromosome("ttfuf").genes() == "ttfuf"); } +BOOST_AUTO_TEST_CASE(constructor_should_allow_genes_that_do_not_correspond_to_any_step) +{ + assert(OptimiserSuite::stepAbbreviationToNameMap().count('.') == 0); + assert(OptimiserSuite::stepAbbreviationToNameMap().count('b') == 0); + + BOOST_TEST(Chromosome(".").genes() == "."); + BOOST_TEST(Chromosome("a..abatbb").genes() == "a..abatbb"); +} + BOOST_AUTO_TEST_CASE(output_operator_should_create_concise_and_unambiguous_string_representation) { vector allSteps; diff --git a/tools/yulPhaser/Chromosome.cpp b/tools/yulPhaser/Chromosome.cpp index c0e401800..687c669da 100644 --- a/tools/yulPhaser/Chromosome.cpp +++ b/tools/yulPhaser/Chromosome.cpp @@ -67,6 +67,11 @@ string const& Chromosome::randomOptimisationStep() return stepNames[SimulationRNG::uniformInt(0, stepNames.size() - 1)]; } +char Chromosome::randomGene() +{ + return OptimiserSuite::stepNameToAbbreviationMap().at(randomOptimisationStep()); +} + string Chromosome::stepsToGenes(vector const& _optimisationSteps) { string genes; diff --git a/tools/yulPhaser/Chromosome.h b/tools/yulPhaser/Chromosome.h index 0e7d1bb3f..96477086f 100644 --- a/tools/yulPhaser/Chromosome.h +++ b/tools/yulPhaser/Chromosome.h @@ -44,6 +44,8 @@ public: explicit Chromosome(std::vector _optimisationSteps): m_genes(stepsToGenes(_optimisationSteps)) {} explicit Chromosome(std::string _genes): + // NOTE: We don't validate the genes - they're only checked at the point of conversion to + // actual optimisation steps names. This is very convenient in mutation tests. m_genes(std::move(_genes)) {} static Chromosome makeRandom(size_t _length); @@ -58,6 +60,7 @@ public: bool operator!=(Chromosome const& _other) const { return !(*this == _other); } static std::string const& randomOptimisationStep(); + static char randomGene(); static std::string stepsToGenes(std::vector const& _optimisationSteps); static std::vector genesToSteps(std::string const& _genes); diff --git a/tools/yulPhaser/Mutations.cpp b/tools/yulPhaser/Mutations.cpp index 61614408d..3e3e91b28 100644 --- a/tools/yulPhaser/Mutations.cpp +++ b/tools/yulPhaser/Mutations.cpp @@ -36,15 +36,15 @@ function phaser::geneRandomisation(double _chance) { return [=](Chromosome const& _chromosome) { - vector optimisationSteps; - for (auto const& step: _chromosome.optimisationSteps()) - optimisationSteps.push_back( + string genes; + for (char gene: _chromosome.genes()) + genes.push_back( SimulationRNG::bernoulliTrial(_chance) ? - Chromosome::randomOptimisationStep() : - step + Chromosome::randomGene() : + gene ); - return Chromosome(move(optimisationSteps)); + return Chromosome(move(genes)); }; } @@ -52,12 +52,12 @@ function phaser::geneDeletion(double _chance) { return [=](Chromosome const& _chromosome) { - vector optimisationSteps; - for (auto const& step: _chromosome.optimisationSteps()) + string genes; + for (char gene: _chromosome.genes()) if (!SimulationRNG::bernoulliTrial(_chance)) - optimisationSteps.push_back(step); + genes.push_back(gene); - return Chromosome(move(optimisationSteps)); + return Chromosome(move(genes)); }; } @@ -65,19 +65,19 @@ function phaser::geneAddition(double _chance) { return [=](Chromosome const& _chromosome) { - vector optimisationSteps; + string genes; if (SimulationRNG::bernoulliTrial(_chance)) - optimisationSteps.push_back(Chromosome::randomOptimisationStep()); + genes.push_back(Chromosome::randomGene()); - for (auto const& step: _chromosome.optimisationSteps()) + for (char gene: _chromosome.genes()) { - optimisationSteps.push_back(step); + genes.push_back(gene); if (SimulationRNG::bernoulliTrial(_chance)) - optimisationSteps.push_back(Chromosome::randomOptimisationStep()); + genes.push_back(Chromosome::randomGene()); } - return Chromosome(move(optimisationSteps)); + return Chromosome(move(genes)); }; }