[yul-phaser] Population: Extract a function for comparing fitness of individuals

- Mostly for readability and convenience. This significantly shortens calls to sort().
- I could define it as Individual::operator< instead but it would be inconsistent with operator== because it does not compare the chromosomes, only fitness. It could result in an unintuitive situation where (a <= b <= a) does not necessarily imply (a == b).
This commit is contained in:
Kamil Śliwak 2020-02-11 19:20:01 +01:00
parent 823e715902
commit 40a6669538
3 changed files with 29 additions and 6 deletions

View File

@ -92,6 +92,24 @@ protected:
BOOST_AUTO_TEST_SUITE(Phaser)
BOOST_AUTO_TEST_SUITE(PopulationTest)
BOOST_AUTO_TEST_CASE(isFitter_should_use_fitness_as_the_main_criterion)
{
BOOST_TEST(isFitter(Individual{Chromosome("a"), 5}, Individual{Chromosome("a"), 10}));
BOOST_TEST(!isFitter(Individual{Chromosome("a"), 10}, Individual{Chromosome("a"), 5}));
BOOST_TEST(isFitter(Individual{Chromosome("aaa"), 5}, Individual{Chromosome("aaaaa"), 10}));
BOOST_TEST(!isFitter(Individual{Chromosome("aaaaa"), 10}, Individual{Chromosome("aaa"), 5}));
BOOST_TEST(isFitter(Individual{Chromosome("aaaaa"), 5}, Individual{Chromosome("aaa"), 10}));
BOOST_TEST(!isFitter(Individual{Chromosome("aaa"), 10}, Individual{Chromosome("aaaaa"), 5}));
}
BOOST_AUTO_TEST_CASE(isFitter_should_return_false_for_identical_individuals)
{
BOOST_TEST(!isFitter(Individual{Chromosome("a"), 3}, Individual{Chromosome("a"), 3}));
BOOST_TEST(!isFitter(Individual{Chromosome("acT"), 0}, Individual{Chromosome("acT"), 0}));
}
BOOST_FIXTURE_TEST_CASE(constructor_should_copy_chromosomes_and_not_compute_fitness, PopulationFixture)
{
vector<Chromosome> chromosomes = {

View File

@ -48,6 +48,13 @@ ostream& phaser::operator<<(ostream& _stream, Individual const& _individual)
return _stream;
}
bool phaser::isFitter(Individual const& a, Individual const& b)
{
assert(a.fitness.has_value() && b.fitness.has_value());
return a.fitness.value() < b.fitness.value();
}
Population::Population(Program _program, vector<Chromosome> const& _chromosomes):
m_program{move(_program)}
{
@ -128,12 +135,7 @@ void Population::doSelection()
{
assert(all_of(m_individuals.begin(), m_individuals.end(), [](auto& i){ return i.fitness.has_value(); }));
sort(
m_individuals.begin(),
m_individuals.end(),
[](auto const& a, auto const& b){ return a.fitness.value() < b.fitness.value(); }
);
sort(m_individuals.begin(), m_individuals.end(), isFitter);
randomizeWorstChromosomes(m_individuals, m_individuals.size() / 2);
}

View File

@ -40,6 +40,9 @@ struct Individual
friend std::ostream& operator<<(std::ostream& _stream, Individual const& _individual);
};
/// Determines which individual is better by comparing fitness values.
bool isFitter(Individual const& a, Individual const& b);
/**
* Represents a changing set of individuals undergoing a genetic algorithm.
* Each round of the algorithm involves mutating existing individuals, evaluating their fitness