mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[yul-phaser] Mutations: Add symmetricRandomPointCrossover()
This commit is contained in:
parent
b6f8ecf755
commit
0837a62d5c
@ -225,6 +225,20 @@ BOOST_AUTO_TEST_CASE(randomPointCrossover_should_swap_chromosome_parts_at_random
|
|||||||
BOOST_TEST(result2 == Chromosome("cccaaaaaaa"));
|
BOOST_TEST(result2 == Chromosome("cccaaaaaaa"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(symmetricRandomPointCrossover_should_swap_chromosome_parts_at_random_point)
|
||||||
|
{
|
||||||
|
function<SymmetricCrossover> crossover = symmetricRandomPointCrossover();
|
||||||
|
|
||||||
|
SimulationRNG::reset(1);
|
||||||
|
tuple<Chromosome, Chromosome> result1 = crossover(Chromosome("aaaaaaaaaa"), Chromosome("cccccc"));
|
||||||
|
tuple<Chromosome, Chromosome> expectedPair1 = {Chromosome("aaaccc"), Chromosome("cccaaaaaaa")};
|
||||||
|
BOOST_TEST(result1 == expectedPair1);
|
||||||
|
|
||||||
|
tuple<Chromosome, Chromosome> result2 = crossover(Chromosome("cccccc"), Chromosome("aaaaaaaaaa"));
|
||||||
|
tuple<Chromosome, Chromosome> expectedPair2 = {Chromosome("ccccccaaaa"), Chromosome("aaaaaa")};
|
||||||
|
BOOST_TEST(result2 == expectedPair2);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(randomPointCrossover_should_only_consider_points_available_on_both_chromosomes)
|
BOOST_AUTO_TEST_CASE(randomPointCrossover_should_only_consider_points_available_on_both_chromosomes)
|
||||||
{
|
{
|
||||||
SimulationRNG::reset(1);
|
SimulationRNG::reset(1);
|
||||||
|
@ -98,7 +98,7 @@ function<Mutation> phaser::alternativeMutations(
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
Chromosome buildChromosomesBySwappingParts(
|
ChromosomePair fixedPointSwap(
|
||||||
Chromosome const& _chromosome1,
|
Chromosome const& _chromosome1,
|
||||||
Chromosome const& _chromosome2,
|
Chromosome const& _chromosome2,
|
||||||
size_t _crossoverPoint
|
size_t _crossoverPoint
|
||||||
@ -109,11 +109,19 @@ Chromosome buildChromosomesBySwappingParts(
|
|||||||
|
|
||||||
auto begin1 = _chromosome1.optimisationSteps().begin();
|
auto begin1 = _chromosome1.optimisationSteps().begin();
|
||||||
auto begin2 = _chromosome2.optimisationSteps().begin();
|
auto begin2 = _chromosome2.optimisationSteps().begin();
|
||||||
|
auto end1 = _chromosome1.optimisationSteps().end();
|
||||||
|
auto end2 = _chromosome2.optimisationSteps().end();
|
||||||
|
|
||||||
return Chromosome(
|
return {
|
||||||
vector<string>(begin1, begin1 + _crossoverPoint) +
|
Chromosome(
|
||||||
vector<string>(begin2 + _crossoverPoint, _chromosome2.optimisationSteps().end())
|
vector<string>(begin1, begin1 + _crossoverPoint) +
|
||||||
);
|
vector<string>(begin2 + _crossoverPoint, end2)
|
||||||
|
),
|
||||||
|
Chromosome(
|
||||||
|
vector<string>(begin2, begin2 + _crossoverPoint) +
|
||||||
|
vector<string>(begin1 + _crossoverPoint, end1)
|
||||||
|
),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -129,7 +137,22 @@ function<Crossover> phaser::randomPointCrossover()
|
|||||||
assert(minPoint <= minLength);
|
assert(minPoint <= minLength);
|
||||||
|
|
||||||
size_t randomPoint = SimulationRNG::uniformInt(minPoint, minLength);
|
size_t randomPoint = SimulationRNG::uniformInt(minPoint, minLength);
|
||||||
return buildChromosomesBySwappingParts(_chromosome1, _chromosome2, randomPoint);
|
return get<0>(fixedPointSwap(_chromosome1, _chromosome2, randomPoint));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function<SymmetricCrossover> phaser::symmetricRandomPointCrossover()
|
||||||
|
{
|
||||||
|
return [=](Chromosome const& _chromosome1, Chromosome const& _chromosome2)
|
||||||
|
{
|
||||||
|
size_t minLength = min(_chromosome1.length(), _chromosome2.length());
|
||||||
|
|
||||||
|
// Don't use position 0 (because this just swaps the values) unless it's the only choice.
|
||||||
|
size_t minPoint = (minLength > 0? 1 : 0);
|
||||||
|
assert(minPoint <= minLength);
|
||||||
|
|
||||||
|
size_t randomPoint = SimulationRNG::uniformInt(minPoint, minLength);
|
||||||
|
return fixedPointSwap(_chromosome1, _chromosome2, randomPoint);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +165,6 @@ function<Crossover> phaser::fixedPointCrossover(double _crossoverPoint)
|
|||||||
size_t minLength = min(_chromosome1.length(), _chromosome2.length());
|
size_t minLength = min(_chromosome1.length(), _chromosome2.length());
|
||||||
size_t concretePoint = static_cast<size_t>(round(minLength * _crossoverPoint));
|
size_t concretePoint = static_cast<size_t>(round(minLength * _crossoverPoint));
|
||||||
|
|
||||||
return buildChromosomesBySwappingParts(_chromosome1, _chromosome2, concretePoint);
|
return get<0>(fixedPointSwap(_chromosome1, _chromosome2, concretePoint));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,11 @@
|
|||||||
namespace solidity::phaser
|
namespace solidity::phaser
|
||||||
{
|
{
|
||||||
|
|
||||||
|
using ChromosomePair = std::tuple<Chromosome, Chromosome>;
|
||||||
|
|
||||||
using Mutation = Chromosome(Chromosome const&);
|
using Mutation = Chromosome(Chromosome const&);
|
||||||
using Crossover = Chromosome(Chromosome const&, Chromosome const&);
|
using Crossover = Chromosome(Chromosome const&, Chromosome const&);
|
||||||
|
using SymmetricCrossover = ChromosomePair(Chromosome const&, Chromosome const&);
|
||||||
|
|
||||||
// MUTATIONS
|
// MUTATIONS
|
||||||
|
|
||||||
@ -61,6 +64,10 @@ std::function<Mutation> alternativeMutations(
|
|||||||
/// position at which to perform perform @a fixedPointCrossover.
|
/// position at which to perform perform @a fixedPointCrossover.
|
||||||
std::function<Crossover> randomPointCrossover();
|
std::function<Crossover> randomPointCrossover();
|
||||||
|
|
||||||
|
/// Symmetric version of @a randomPointCrossover(). Creates an operator that returns a pair
|
||||||
|
/// containing both possible results for the same crossover point.
|
||||||
|
std::function<SymmetricCrossover> symmetricRandomPointCrossover();
|
||||||
|
|
||||||
/// Creates a crossover operator that always chooses a point that lies at @a _crossoverPoint
|
/// Creates a crossover operator that always chooses a point that lies at @a _crossoverPoint
|
||||||
/// percent of the length of the shorter chromosome. Then creates a new chromosome by
|
/// percent of the length of the shorter chromosome. Then creates a new chromosome by
|
||||||
/// splitting both inputs at the crossover point and stitching output from the first half or first
|
/// splitting both inputs at the crossover point and stitching output from the first half or first
|
||||||
|
Loading…
Reference in New Issue
Block a user