[yul-phaser] Chromosome: Make it possible to use genes that do not correspond to existing optimiser steps

This commit is contained in:
Kamil Śliwak 2020-09-11 20:49:25 +02:00 committed by chriseth
parent fb205b719e
commit d75f0ba437
4 changed files with 33 additions and 16 deletions

View File

@ -120,6 +120,15 @@ BOOST_AUTO_TEST_CASE(constructor_should_allow_duplicate_steps)
BOOST_TEST(Chromosome("ttfuf").genes() == "ttfuf"); 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) BOOST_AUTO_TEST_CASE(output_operator_should_create_concise_and_unambiguous_string_representation)
{ {
vector<string> allSteps; vector<string> allSteps;

View File

@ -67,6 +67,11 @@ string const& Chromosome::randomOptimisationStep()
return stepNames[SimulationRNG::uniformInt(0, stepNames.size() - 1)]; return stepNames[SimulationRNG::uniformInt(0, stepNames.size() - 1)];
} }
char Chromosome::randomGene()
{
return OptimiserSuite::stepNameToAbbreviationMap().at(randomOptimisationStep());
}
string Chromosome::stepsToGenes(vector<string> const& _optimisationSteps) string Chromosome::stepsToGenes(vector<string> const& _optimisationSteps)
{ {
string genes; string genes;

View File

@ -44,6 +44,8 @@ public:
explicit Chromosome(std::vector<std::string> _optimisationSteps): explicit Chromosome(std::vector<std::string> _optimisationSteps):
m_genes(stepsToGenes(_optimisationSteps)) {} m_genes(stepsToGenes(_optimisationSteps)) {}
explicit Chromosome(std::string _genes): 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)) {} m_genes(std::move(_genes)) {}
static Chromosome makeRandom(size_t _length); static Chromosome makeRandom(size_t _length);
@ -58,6 +60,7 @@ public:
bool operator!=(Chromosome const& _other) const { return !(*this == _other); } bool operator!=(Chromosome const& _other) const { return !(*this == _other); }
static std::string const& randomOptimisationStep(); static std::string const& randomOptimisationStep();
static char randomGene();
static std::string stepsToGenes(std::vector<std::string> const& _optimisationSteps); static std::string stepsToGenes(std::vector<std::string> const& _optimisationSteps);
static std::vector<std::string> genesToSteps(std::string const& _genes); static std::vector<std::string> genesToSteps(std::string const& _genes);

View File

@ -36,15 +36,15 @@ function<Mutation> phaser::geneRandomisation(double _chance)
{ {
return [=](Chromosome const& _chromosome) return [=](Chromosome const& _chromosome)
{ {
vector<string> optimisationSteps; string genes;
for (auto const& step: _chromosome.optimisationSteps()) for (char gene: _chromosome.genes())
optimisationSteps.push_back( genes.push_back(
SimulationRNG::bernoulliTrial(_chance) ? SimulationRNG::bernoulliTrial(_chance) ?
Chromosome::randomOptimisationStep() : Chromosome::randomGene() :
step gene
); );
return Chromosome(move(optimisationSteps)); return Chromosome(move(genes));
}; };
} }
@ -52,12 +52,12 @@ function<Mutation> phaser::geneDeletion(double _chance)
{ {
return [=](Chromosome const& _chromosome) return [=](Chromosome const& _chromosome)
{ {
vector<string> optimisationSteps; string genes;
for (auto const& step: _chromosome.optimisationSteps()) for (char gene: _chromosome.genes())
if (!SimulationRNG::bernoulliTrial(_chance)) 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<Mutation> phaser::geneAddition(double _chance)
{ {
return [=](Chromosome const& _chromosome) return [=](Chromosome const& _chromosome)
{ {
vector<string> optimisationSteps; string genes;
if (SimulationRNG::bernoulliTrial(_chance)) 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)) if (SimulationRNG::bernoulliTrial(_chance))
optimisationSteps.push_back(Chromosome::randomOptimisationStep()); genes.push_back(Chromosome::randomGene());
} }
return Chromosome(move(optimisationSteps)); return Chromosome(move(genes));
}; };
} }