mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[yul-phaser] Phaser: Refactor object creation in runAlgorithm() into a set of factories
This commit is contained in:
parent
25e81f6bd3
commit
2d177c7623
@ -68,10 +68,77 @@ ostream& phaser::operator<<(ostream& _outputStream, Algorithm _algorithm)
|
||||
return _outputStream;
|
||||
}
|
||||
|
||||
namespace
|
||||
GeneticAlgorithmFactory::Options GeneticAlgorithmFactory::Options::fromCommandLine(po::variables_map const& _arguments)
|
||||
{
|
||||
return {
|
||||
_arguments["algorithm"].as<Algorithm>(),
|
||||
};
|
||||
}
|
||||
|
||||
CharStream loadSource(string const& _sourcePath)
|
||||
unique_ptr<GeneticAlgorithm> GeneticAlgorithmFactory::build(
|
||||
Options const& _options,
|
||||
size_t _populationSize,
|
||||
size_t _minChromosomeLength,
|
||||
size_t _maxChromosomeLength
|
||||
)
|
||||
{
|
||||
assert(_populationSize > 0);
|
||||
|
||||
switch (_options.algorithm)
|
||||
{
|
||||
case Algorithm::Random:
|
||||
return make_unique<RandomAlgorithm>(RandomAlgorithm::Options{
|
||||
/* elitePoolSize = */ 1.0 / _populationSize,
|
||||
/* minChromosomeLength = */ _minChromosomeLength,
|
||||
/* maxChromosomeLength = */ _maxChromosomeLength,
|
||||
});
|
||||
case Algorithm::GEWEP:
|
||||
return make_unique<GenerationalElitistWithExclusivePools>(GenerationalElitistWithExclusivePools::Options{
|
||||
/* mutationPoolSize = */ 0.25,
|
||||
/* crossoverPoolSize = */ 0.25,
|
||||
/* randomisationChance = */ 0.9,
|
||||
/* deletionVsAdditionChance = */ 0.5,
|
||||
/* percentGenesToRandomise = */ 1.0 / _maxChromosomeLength,
|
||||
/* percentGenesToAddOrDelete = */ 1.0 / _maxChromosomeLength,
|
||||
});
|
||||
default:
|
||||
assertThrow(false, solidity::util::Exception, "Invalid Algorithm value.");
|
||||
}
|
||||
}
|
||||
|
||||
unique_ptr<FitnessMetric> FitnessMetricFactory::build(
|
||||
Program _program
|
||||
)
|
||||
{
|
||||
return make_unique<ProgramSize>(move(_program), RepetitionCount);
|
||||
}
|
||||
|
||||
Population PopulationFactory::build(
|
||||
shared_ptr<FitnessMetric> _fitnessMetric
|
||||
)
|
||||
{
|
||||
return Population::makeRandom(
|
||||
move(_fitnessMetric),
|
||||
PopulationSize,
|
||||
MinChromosomeLength,
|
||||
MaxChromosomeLength
|
||||
);
|
||||
}
|
||||
|
||||
ProgramFactory::Options ProgramFactory::Options::fromCommandLine(po::variables_map const& _arguments)
|
||||
{
|
||||
return {
|
||||
_arguments["input-file"].as<string>(),
|
||||
};
|
||||
}
|
||||
|
||||
Program ProgramFactory::build(Options const& _options)
|
||||
{
|
||||
CharStream sourceCode = loadSource(_options.inputFile);
|
||||
return Program::load(sourceCode);
|
||||
}
|
||||
|
||||
CharStream ProgramFactory::loadSource(string const& _sourcePath)
|
||||
{
|
||||
assertThrow(boost::filesystem::exists(_sourcePath), InvalidProgram, "Source file does not exist");
|
||||
|
||||
@ -79,8 +146,6 @@ CharStream loadSource(string const& _sourcePath)
|
||||
return CharStream(sourceCode, _sourcePath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int Phaser::main(int _argc, char** _argv)
|
||||
{
|
||||
CommandLineParsingResult parsingResult = parseCommandLine(_argc, _argv);
|
||||
@ -89,10 +154,7 @@ int Phaser::main(int _argc, char** _argv)
|
||||
|
||||
initialiseRNG(parsingResult.arguments);
|
||||
|
||||
runAlgorithm(
|
||||
parsingResult.arguments["input-file"].as<string>(),
|
||||
parsingResult.arguments["algorithm"].as<Algorithm>()
|
||||
);
|
||||
runAlgorithm(parsingResult.arguments);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -167,46 +229,22 @@ void Phaser::initialiseRNG(po::variables_map const& _arguments)
|
||||
cout << "Random seed: " << seed << endl;
|
||||
}
|
||||
|
||||
void Phaser::runAlgorithm(string const& _sourcePath, Algorithm _algorithm)
|
||||
void Phaser::runAlgorithm(po::variables_map const& _arguments)
|
||||
{
|
||||
constexpr size_t populationSize = 20;
|
||||
constexpr size_t minChromosomeLength = 12;
|
||||
constexpr size_t maxChromosomeLength = 30;
|
||||
auto programOptions = ProgramFactory::Options::fromCommandLine(_arguments);
|
||||
auto algorithmOptions = GeneticAlgorithmFactory::Options::fromCommandLine(_arguments);
|
||||
|
||||
CharStream sourceCode = loadSource(_sourcePath);
|
||||
shared_ptr<FitnessMetric> fitnessMetric = make_shared<ProgramSize>(Program::load(sourceCode), 5);
|
||||
auto population = Population::makeRandom(
|
||||
fitnessMetric,
|
||||
populationSize,
|
||||
minChromosomeLength,
|
||||
maxChromosomeLength
|
||||
Program program = ProgramFactory::build(programOptions);
|
||||
unique_ptr<FitnessMetric> fitnessMetric = FitnessMetricFactory::build(move(program));
|
||||
Population population = PopulationFactory::build(move(fitnessMetric));
|
||||
|
||||
unique_ptr<GeneticAlgorithm> geneticAlgorithm = GeneticAlgorithmFactory::build(
|
||||
algorithmOptions,
|
||||
population.individuals().size(),
|
||||
PopulationFactory::MinChromosomeLength,
|
||||
PopulationFactory::MaxChromosomeLength
|
||||
);
|
||||
|
||||
AlgorithmRunner algorithmRunner(population, AlgorithmRunner::Options{}, cout);
|
||||
switch (_algorithm)
|
||||
{
|
||||
case Algorithm::Random:
|
||||
{
|
||||
RandomAlgorithm algorithm({
|
||||
/* elitePoolSize = */ 1.0 / populationSize,
|
||||
/* minChromosomeLength = */ minChromosomeLength,
|
||||
/* maxChromosomeLength = */ maxChromosomeLength,
|
||||
});
|
||||
algorithmRunner.run(algorithm);
|
||||
break;
|
||||
}
|
||||
case Algorithm::GEWEP:
|
||||
{
|
||||
GenerationalElitistWithExclusivePools algorithm({
|
||||
/* mutationPoolSize = */ 0.25,
|
||||
/* crossoverPoolSize = */ 0.25,
|
||||
/* randomisationChance = */ 0.9,
|
||||
/* deletionVsAdditionChance = */ 0.5,
|
||||
/* percentGenesToRandomise = */ 1.0 / maxChromosomeLength,
|
||||
/* percentGenesToAddOrDelete = */ 1.0 / maxChromosomeLength,
|
||||
});
|
||||
algorithmRunner.run(algorithm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
algorithmRunner.run(*geneticAlgorithm);
|
||||
}
|
||||
|
@ -15,7 +15,8 @@
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* Contains the main class that controls yul-phaser based on command-line parameters.
|
||||
* Contains the main class that controls yul-phaser based on command-line parameters and
|
||||
* associated factories for building instances of phaser's components.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -23,12 +24,25 @@
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
namespace solidity::langutil
|
||||
{
|
||||
|
||||
class CharStream;
|
||||
|
||||
}
|
||||
|
||||
namespace solidity::phaser
|
||||
{
|
||||
|
||||
class FitnessMetric;
|
||||
class GeneticAlgorithm;
|
||||
class Population;
|
||||
class Program;
|
||||
|
||||
enum class Algorithm
|
||||
{
|
||||
Random,
|
||||
@ -38,10 +52,78 @@ enum class Algorithm
|
||||
std::istream& operator>>(std::istream& _inputStream, solidity::phaser::Algorithm& _algorithm);
|
||||
std::ostream& operator<<(std::ostream& _outputStream, solidity::phaser::Algorithm _algorithm);
|
||||
|
||||
/**
|
||||
* Builds and validates instances of @a GeneticAlgorithm and its derived classes.
|
||||
*/
|
||||
class GeneticAlgorithmFactory
|
||||
{
|
||||
public:
|
||||
struct Options
|
||||
{
|
||||
Algorithm algorithm;
|
||||
|
||||
static Options fromCommandLine(boost::program_options::variables_map const& _arguments);
|
||||
};
|
||||
|
||||
static std::unique_ptr<GeneticAlgorithm> build(
|
||||
Options const& _options,
|
||||
size_t _populationSize,
|
||||
size_t _minChromosomeLength,
|
||||
size_t _maxChromosomeLength
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds and validates instances of @a FitnessMetric and its derived classes.
|
||||
*/
|
||||
class FitnessMetricFactory
|
||||
{
|
||||
public:
|
||||
static constexpr size_t RepetitionCount = 5;
|
||||
|
||||
static std::unique_ptr<FitnessMetric> build(
|
||||
Program _program
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds and validates instances of @a Population.
|
||||
*/
|
||||
class PopulationFactory
|
||||
{
|
||||
public:
|
||||
static constexpr size_t PopulationSize = 20;
|
||||
static constexpr size_t MinChromosomeLength = 12;
|
||||
static constexpr size_t MaxChromosomeLength = 30;
|
||||
|
||||
static Population build(
|
||||
std::shared_ptr<FitnessMetric> _fitnessMetric
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds and validates instances of @a Program.
|
||||
*/
|
||||
class ProgramFactory
|
||||
{
|
||||
public:
|
||||
struct Options
|
||||
{
|
||||
std::string inputFile;
|
||||
|
||||
static Options fromCommandLine(boost::program_options::variables_map const& _arguments);
|
||||
};
|
||||
|
||||
static Program build(Options const& _options);
|
||||
|
||||
private:
|
||||
static langutil::CharStream loadSource(std::string const& _sourcePath);
|
||||
};
|
||||
|
||||
/**
|
||||
* Main class that controls yul-phaser based on command-line parameters. The class is responsible
|
||||
* for command-line parsing, initialisation of global objects (like the random number generator),
|
||||
* creating instances of main components and feeding them into @a AlgorithmRunner.
|
||||
* creating instances of main components using factories and feeding them into @a AlgorithmRunner.
|
||||
*/
|
||||
class Phaser
|
||||
{
|
||||
@ -58,7 +140,7 @@ private:
|
||||
static CommandLineParsingResult parseCommandLine(int _argc, char** _argv);
|
||||
static void initialiseRNG(boost::program_options::variables_map const& _arguments);
|
||||
|
||||
static void runAlgorithm(std::string const& _sourcePath, Algorithm _algorithm);
|
||||
static void runAlgorithm(boost::program_options::variables_map const& _arguments);
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user