[yul-phaser] Population: Keep the individuals always sorted

This commit is contained in:
cameel 2020-02-05 16:49:50 +01:00 committed by Kamil Śliwak
parent 76842ac3fd
commit cef01c961a
3 changed files with 13 additions and 10 deletions

View File

@ -81,20 +81,24 @@ BOOST_AUTO_TEST_CASE(isFitter_should_return_false_for_identical_individuals)
BOOST_TEST(!isFitter(Individual{Chromosome("acT"), 0}, Individual{Chromosome("acT"), 0})); BOOST_TEST(!isFitter(Individual{Chromosome("acT"), 0}, Individual{Chromosome("acT"), 0}));
} }
BOOST_FIXTURE_TEST_CASE(constructor_should_copy_chromosomes_and_compute_fitness, PopulationFixture) BOOST_FIXTURE_TEST_CASE(constructor_should_copy_chromosomes_compute_fitness_and_sort_chromosomes, PopulationFixture)
{ {
vector<Chromosome> chromosomes = { vector<Chromosome> chromosomes = {
Chromosome::makeRandom(5), Chromosome::makeRandom(5),
Chromosome::makeRandom(15),
Chromosome::makeRandom(10), Chromosome::makeRandom(10),
}; };
Population population(m_fitnessMetric, chromosomes); Population population(m_fitnessMetric, chromosomes);
BOOST_TEST(population.individuals().size() == 2); vector<Individual> const& individuals = population.individuals();
BOOST_TEST(population.individuals()[0].chromosome == chromosomes[0]);
BOOST_TEST(population.individuals()[1].chromosome == chromosomes[1]);
BOOST_TEST(population.individuals()[0].fitness == m_fitnessMetric->evaluate(population.individuals()[0].chromosome)); BOOST_TEST(individuals.size() == 3);
BOOST_TEST(population.individuals()[1].fitness == m_fitnessMetric->evaluate(population.individuals()[1].chromosome)); BOOST_TEST(individuals[0].fitness == 5);
BOOST_TEST(individuals[1].fitness == 10);
BOOST_TEST(individuals[2].fitness == 15);
BOOST_TEST(individuals[0].chromosome == chromosomes[0]);
BOOST_TEST(individuals[1].chromosome == chromosomes[2]);
BOOST_TEST(individuals[2].chromosome == chromosomes[1]);
} }
BOOST_FIXTURE_TEST_CASE(makeRandom_should_get_chromosome_lengths_from_specified_generator, PopulationFixture) BOOST_FIXTURE_TEST_CASE(makeRandom_should_get_chromosome_lengths_from_specified_generator, PopulationFixture)

View File

@ -128,8 +128,8 @@ void Population::doMutation()
void Population::doSelection() void Population::doSelection()
{ {
m_individuals = sortedIndividuals(move(m_individuals));
randomizeWorstChromosomes(*m_fitnessMetric, m_individuals, m_individuals.size() / 2); randomizeWorstChromosomes(*m_fitnessMetric, m_individuals, m_individuals.size() / 2);
m_individuals = sortedIndividuals(move(m_individuals));
} }
void Population::randomizeWorstChromosomes( void Population::randomizeWorstChromosomes(

View File

@ -65,8 +65,7 @@ bool isFitter(Individual const& a, Individual const& b);
* and selecting the best ones for the next round. * and selecting the best ones for the next round.
* *
* An individual is a sequence of optimiser steps represented by a @a Chromosome instance. * An individual is a sequence of optimiser steps represented by a @a Chromosome instance.
* Individuals are stored together with a fitness value that can be computed by the fitness metric * Individuals are always ordered by their fitness (based on @_fitnessMetric and @a isFitter()).
* associated with the population.
* The fitness is computed using the metric as soon as an individual is inserted into the population. * The fitness is computed using the metric as soon as an individual is inserted into the population.
*/ */
class Population class Population
@ -112,7 +111,7 @@ public:
private: private:
explicit Population(std::shared_ptr<FitnessMetric const> _fitnessMetric, std::vector<Individual> _individuals): explicit Population(std::shared_ptr<FitnessMetric const> _fitnessMetric, std::vector<Individual> _individuals):
m_fitnessMetric(std::move(_fitnessMetric)), m_fitnessMetric(std::move(_fitnessMetric)),
m_individuals{std::move(_individuals)} {} m_individuals{sortedIndividuals(std::move(_individuals))} {}
void doMutation(); void doMutation();
void doSelection(); void doSelection();