diff --git a/tools/yulPhaser/Phaser.cpp b/tools/yulPhaser/Phaser.cpp index 97e429968..b1ee03f56 100644 --- a/tools/yulPhaser/Phaser.cpp +++ b/tools/yulPhaser/Phaser.cpp @@ -64,6 +64,19 @@ GeneticAlgorithmFactory::Options GeneticAlgorithmFactory::Options::fromCommandLi _arguments["algorithm"].as(), _arguments["min-chromosome-length"].as(), _arguments["max-chromosome-length"].as(), + _arguments.count("random-elite-pool-size") > 0 ? + _arguments["random-elite-pool-size"].as() : + optional{}, + _arguments["gewep-mutation-pool-size"].as(), + _arguments["gewep-crossover-pool-size"].as(), + _arguments["gewep-randomisation-chance"].as(), + _arguments["gewep-deletion-vs-addition-chance"].as(), + _arguments.count("gewep-genes-to-randomise") > 0 ? + _arguments["gewep-genes-to-randomise"].as() : + optional{}, + _arguments.count("gewep-genes-to-add-or-delete") > 0 ? + _arguments["gewep-genes-to-add-or-delete"].as() : + optional{}, }; } @@ -77,20 +90,37 @@ unique_ptr GeneticAlgorithmFactory::build( switch (_options.algorithm) { case Algorithm::Random: + { + double elitePoolSize = 1.0 / _populationSize; + + if (_options.randomElitePoolSize.has_value()) + elitePoolSize = _options.randomElitePoolSize.value(); + return make_unique(RandomAlgorithm::Options{ - /* elitePoolSize = */ 1.0 / _populationSize, + /* elitePoolSize = */ elitePoolSize, /* minChromosomeLength = */ _options.minChromosomeLength, /* maxChromosomeLength = */ _options.maxChromosomeLength, }); + } case Algorithm::GEWEP: + { + double percentGenesToRandomise = 1.0 / _options.maxChromosomeLength; + double percentGenesToAddOrDelete = percentGenesToRandomise; + + if (_options.gewepGenesToRandomise.has_value()) + percentGenesToRandomise = _options.gewepGenesToRandomise.value(); + if (_options.gewepGenesToAddOrDelete.has_value()) + percentGenesToAddOrDelete = _options.gewepGenesToAddOrDelete.value(); + return make_unique(GenerationalElitistWithExclusivePools::Options{ - /* mutationPoolSize = */ 0.25, - /* crossoverPoolSize = */ 0.25, - /* randomisationChance = */ 0.9, - /* deletionVsAdditionChance = */ 0.5, - /* percentGenesToRandomise = */ 1.0 / _options.maxChromosomeLength, - /* percentGenesToAddOrDelete = */ 1.0 / _options.maxChromosomeLength, + /* mutationPoolSize = */ _options.gewepMutationPoolSize, + /* crossoverPoolSize = */ _options.gewepCrossoverPoolSize, + /* randomisationChance = */ _options.gewepRandomisationChance, + /* deletionVsAdditionChance = */ _options.gewepDeletionVsAdditionChance, + /* percentGenesToRandomise = */ percentGenesToRandomise, + /* percentGenesToAddOrDelete = */ percentGenesToAddOrDelete, }); + } default: assertThrow(false, solidity::util::Exception, "Invalid Algorithm value."); } @@ -277,6 +307,54 @@ Phaser::CommandLineDescription Phaser::buildCommandLineDescription() ; keywordDescription.add(algorithmDescription); + po::options_description gewepAlgorithmDescription("GEWEP ALGORITHM", lineLength, minDescriptionLength); + gewepAlgorithmDescription.add_options() + ( + "gewep-mutation-pool-size", + po::value()->value_name("")->default_value(0.25), + "Percentage of population to regenerate using mutations in each round." + ) + ( + "gewep-crossover-pool-size", + po::value()->value_name("")->default_value(0.25), + "Percentage of population to regenerate using crossover in each round." + ) + ( + "gewep-randomisation-chance", + po::value()->value_name("")->default_value(0.9), + "The chance of choosing gene randomisation as the mutation to perform." + ) + ( + "gewep-deletion-vs-addition-chance", + po::value()->value_name("")->default_value(0.5), + "The chance of choosing gene deletion as the mutation if randomisation was not chosen." + ) + ( + "gewep-genes-to-randomise", + po::value()->value_name(""), + "The chance of any given gene being mutated in gene randomisation. " + "(default=1/max-chromosome-length)" + ) + ( + "gewep-genes-to-add-or-delete", + po::value()->value_name(""), + "The chance of a gene being added (or deleted) in gene addition (or deletion). " + "(default=1/max-chromosome-length)" + ) + ; + keywordDescription.add(gewepAlgorithmDescription); + + po::options_description randomAlgorithmDescription("RANDOM ALGORITHM", lineLength, minDescriptionLength); + randomAlgorithmDescription.add_options() + ( + "random-elite-pool-size", + po::value()->value_name(""), + "Percentage of the population preserved in each round. " + "(default=one individual, regardless of population size)" + ) + ; + keywordDescription.add(randomAlgorithmDescription); + po::options_description populationDescription("POPULATION", lineLength, minDescriptionLength); populationDescription.add_options() ( diff --git a/tools/yulPhaser/Phaser.h b/tools/yulPhaser/Phaser.h index b45a9dd6e..9631aa4cb 100644 --- a/tools/yulPhaser/Phaser.h +++ b/tools/yulPhaser/Phaser.h @@ -66,6 +66,13 @@ public: Algorithm algorithm; size_t minChromosomeLength; size_t maxChromosomeLength; + std::optional randomElitePoolSize; + double gewepMutationPoolSize; + double gewepCrossoverPoolSize; + double gewepRandomisationChance; + double gewepDeletionVsAdditionChance; + std::optional gewepGenesToRandomise; + std::optional gewepGenesToAddOrDelete; static Options fromCommandLine(boost::program_options::variables_map const& _arguments); };