mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[yul-phaser] Population: Add symmetricCrossoverWithRemainder()
This commit is contained in:
parent
59011fcde6
commit
ef8d0888af
@ -48,6 +48,14 @@ namespace solidity::phaser::test
|
|||||||
class PopulationFixture
|
class PopulationFixture
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
static ChromosomePair twoStepSwap(Chromosome const& _chromosome1, Chromosome const& _chromosome2)
|
||||||
|
{
|
||||||
|
return ChromosomePair{
|
||||||
|
Chromosome(vector<string>{_chromosome1.optimisationSteps()[0], _chromosome2.optimisationSteps()[1]}),
|
||||||
|
Chromosome(vector<string>{_chromosome2.optimisationSteps()[0], _chromosome1.optimisationSteps()[1]}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<FitnessMetric> m_fitnessMetric = make_shared<ChromosomeLengthMetric>();
|
shared_ptr<FitnessMetric> m_fitnessMetric = make_shared<ChromosomeLengthMetric>();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -309,6 +317,53 @@ BOOST_FIXTURE_TEST_CASE(crossover_should_return_empty_population_if_selection_is
|
|||||||
BOOST_TEST(population.crossover(selection, fixedPointCrossover(0.5)).individuals().empty());
|
BOOST_TEST(population.crossover(selection, fixedPointCrossover(0.5)).individuals().empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_CASE(symmetricCrossoverWithRemainder_should_return_crossed_population_and_remainder, PopulationFixture)
|
||||||
|
{
|
||||||
|
Population population(m_fitnessMetric, {Chromosome("aa"), Chromosome("cc"), Chromosome("gg"), Chromosome("hh")});
|
||||||
|
PairMosaicSelection selection({{2, 1}}, 0.25);
|
||||||
|
assert(selection.materialise(population.individuals().size()) == (vector<tuple<size_t, size_t>>{{2, 1}}));
|
||||||
|
|
||||||
|
Population expectedCrossedPopulation(m_fitnessMetric, {Chromosome("gc"), Chromosome("cg")});
|
||||||
|
Population expectedRemainder(m_fitnessMetric, {Chromosome("aa"), Chromosome("hh")});
|
||||||
|
|
||||||
|
BOOST_TEST(
|
||||||
|
population.symmetricCrossoverWithRemainder(selection, twoStepSwap) ==
|
||||||
|
(tuple<Population, Population>{expectedCrossedPopulation, expectedRemainder})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_CASE(symmetricCrossoverWithRemainder_should_allow_crossing_the_same_individual_multiple_times, PopulationFixture)
|
||||||
|
{
|
||||||
|
Population population(m_fitnessMetric, {Chromosome("aa"), Chromosome("cc"), Chromosome("gg"), Chromosome("hh")});
|
||||||
|
PairMosaicSelection selection({{0, 0}, {2, 1}}, 1.0);
|
||||||
|
assert(selection.materialise(population.individuals().size()) == (vector<tuple<size_t, size_t>>{{0, 0}, {2, 1}, {0, 0}, {2, 1}}));
|
||||||
|
|
||||||
|
Population expectedCrossedPopulation(m_fitnessMetric, {
|
||||||
|
Chromosome("aa"), Chromosome("aa"),
|
||||||
|
Chromosome("aa"), Chromosome("aa"),
|
||||||
|
Chromosome("gc"), Chromosome("cg"),
|
||||||
|
Chromosome("gc"), Chromosome("cg"),
|
||||||
|
});
|
||||||
|
Population expectedRemainder(m_fitnessMetric, {Chromosome("hh")});
|
||||||
|
|
||||||
|
BOOST_TEST(
|
||||||
|
population.symmetricCrossoverWithRemainder(selection, twoStepSwap) ==
|
||||||
|
(tuple<Population, Population>{expectedCrossedPopulation, expectedRemainder})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_CASE(symmetricCrossoverWithRemainder_should_return_empty_population_if_selection_is_empty, PopulationFixture)
|
||||||
|
{
|
||||||
|
Population population(m_fitnessMetric, {Chromosome("aa"), Chromosome("cc")});
|
||||||
|
PairMosaicSelection selection({}, 0.0);
|
||||||
|
assert(selection.materialise(population.individuals().size()).empty());
|
||||||
|
|
||||||
|
BOOST_TEST(
|
||||||
|
population.symmetricCrossoverWithRemainder(selection, twoStepSwap) ==
|
||||||
|
(tuple<Population, Population>{Population(m_fitnessMetric), population})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
|
@ -117,6 +117,37 @@ Population Population::crossover(PairSelection const& _selection, function<Cross
|
|||||||
return Population(m_fitnessMetric, crossedIndividuals);
|
return Population(m_fitnessMetric, crossedIndividuals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tuple<Population, Population> Population::symmetricCrossoverWithRemainder(
|
||||||
|
PairSelection const& _selection,
|
||||||
|
function<SymmetricCrossover> _symmetricCrossover
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
vector<int> indexSelected(m_individuals.size(), false);
|
||||||
|
|
||||||
|
vector<Individual> crossedIndividuals;
|
||||||
|
for (auto const& [i, j]: _selection.materialise(m_individuals.size()))
|
||||||
|
{
|
||||||
|
auto children = _symmetricCrossover(
|
||||||
|
m_individuals[i].chromosome,
|
||||||
|
m_individuals[j].chromosome
|
||||||
|
);
|
||||||
|
crossedIndividuals.emplace_back(move(get<0>(children)), *m_fitnessMetric);
|
||||||
|
crossedIndividuals.emplace_back(move(get<1>(children)), *m_fitnessMetric);
|
||||||
|
indexSelected[i] = true;
|
||||||
|
indexSelected[j] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<Individual> remainder;
|
||||||
|
for (size_t i = 0; i < indexSelected.size(); ++i)
|
||||||
|
if (!indexSelected[i])
|
||||||
|
remainder.emplace_back(m_individuals[i]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Population(m_fitnessMetric, crossedIndividuals),
|
||||||
|
Population(m_fitnessMetric, remainder),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace solidity::phaser
|
namespace solidity::phaser
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -100,6 +100,10 @@ public:
|
|||||||
Population select(Selection const& _selection) const;
|
Population select(Selection const& _selection) const;
|
||||||
Population mutate(Selection const& _selection, std::function<Mutation> _mutation) const;
|
Population mutate(Selection const& _selection, std::function<Mutation> _mutation) const;
|
||||||
Population crossover(PairSelection const& _selection, std::function<Crossover> _crossover) const;
|
Population crossover(PairSelection const& _selection, std::function<Crossover> _crossover) const;
|
||||||
|
std::tuple<Population, Population> symmetricCrossoverWithRemainder(
|
||||||
|
PairSelection const& _selection,
|
||||||
|
std::function<SymmetricCrossover> _symmetricCrossover
|
||||||
|
) const;
|
||||||
|
|
||||||
friend Population operator+(Population _a, Population _b);
|
friend Population operator+(Population _a, Population _b);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user