mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[yul-phaser] Add randomPointCrossover() and fixedPointCrossover() operators
This commit is contained in:
@@ -19,6 +19,11 @@
|
||||
|
||||
#include <tools/yulPhaser/SimulationRNG.h>
|
||||
|
||||
#include <libsolutil/CommonData.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -89,3 +94,60 @@ function<Mutation> phaser::alternativeMutations(
|
||||
return _mutation2(_chromosome);
|
||||
};
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
ChromosomePair buildChromosomesBySwappingParts(
|
||||
Chromosome const& _chromosome1,
|
||||
Chromosome const& _chromosome2,
|
||||
size_t _crossoverPoint
|
||||
)
|
||||
{
|
||||
assert(_crossoverPoint <= _chromosome1.length());
|
||||
assert(_crossoverPoint <= _chromosome2.length());
|
||||
|
||||
auto begin1 = _chromosome1.optimisationSteps().begin();
|
||||
auto begin2 = _chromosome2.optimisationSteps().begin();
|
||||
|
||||
return ChromosomePair(
|
||||
Chromosome(
|
||||
vector<string>(begin1, begin1 + _crossoverPoint) +
|
||||
vector<string>(begin2 + _crossoverPoint, _chromosome2.optimisationSteps().end())
|
||||
),
|
||||
Chromosome(
|
||||
vector<string>(begin2, begin2 + _crossoverPoint) +
|
||||
vector<string>(begin1 + _crossoverPoint, _chromosome1.optimisationSteps().end())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function<Crossover> phaser::randomPointCrossover()
|
||||
{
|
||||
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 buildChromosomesBySwappingParts(_chromosome1, _chromosome2, randomPoint);
|
||||
};
|
||||
}
|
||||
|
||||
function<Crossover> phaser::fixedPointCrossover(double _crossoverPoint)
|
||||
{
|
||||
assert(0.0 <= _crossoverPoint && _crossoverPoint <= 1.0);
|
||||
|
||||
return [=](Chromosome const& _chromosome1, Chromosome const& _chromosome2)
|
||||
{
|
||||
size_t minLength = min(_chromosome1.length(), _chromosome2.length());
|
||||
size_t concretePoint = static_cast<size_t>(round(minLength * _crossoverPoint));
|
||||
|
||||
return buildChromosomesBySwappingParts(_chromosome1, _chromosome2, concretePoint);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,11 +23,15 @@
|
||||
#include <tools/yulPhaser/Chromosome.h>
|
||||
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
|
||||
namespace solidity::phaser
|
||||
{
|
||||
|
||||
using ChromosomePair = std::tuple<Chromosome, Chromosome>;
|
||||
|
||||
using Mutation = Chromosome(Chromosome const&);
|
||||
using Crossover = ChromosomePair(Chromosome const&, Chromosome const&);
|
||||
|
||||
// MUTATIONS
|
||||
|
||||
@@ -53,4 +57,20 @@ std::function<Mutation> alternativeMutations(
|
||||
std::function<Mutation> _mutation2
|
||||
);
|
||||
|
||||
// CROSSOVER
|
||||
|
||||
/// Creates a crossover operator that randomly selects a number between 0 and 1 and uses it as the
|
||||
/// position at which to perform perform @a fixedPointCrossover.
|
||||
std::function<Crossover> randomPointCrossover();
|
||||
|
||||
/// 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 pair of chromosomes by
|
||||
/// splitting both inputs at the crossover point and stitching the resulting parts. The first
|
||||
/// output is created from the first half or first input and the second half of the second input
|
||||
/// The second output from the remaining two halves.
|
||||
///
|
||||
/// Avoids selecting position 0 (since this just produces a chromosome identical to the second one)
|
||||
/// unless there is no other choice (i.e. one of the chromosomes is empty).
|
||||
std::function<Crossover> fixedPointCrossover(double _crossoverPoint);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user