ian@0: // Copyright 2011, Ian Hobson. ian@0: // ian@0: // This file is part of gpsynth. ian@0: // ian@0: // gpsynth is free software: you can redistribute it and/or modify ian@0: // it under the terms of the GNU General Public License as published by ian@0: // the Free Software Foundation, either version 3 of the License, or ian@0: // (at your option) any later version. ian@0: // ian@0: // gpsynth is distributed in the hope that it will be useful, ian@0: // but WITHOUT ANY WARRANTY; without even the implied warranty of ian@0: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ian@0: // GNU General Public License for more details. ian@0: // ian@0: // You should have received a copy of the GNU General Public License ian@0: // along with gpsynth in the file COPYING. ian@0: // If not, see http://www.gnu.org/licenses/. ian@0: ian@0: #include "file_comparer.hpp" ian@0: #include "graph_helpers.hpp" ian@0: #include "logger.hpp" ian@0: #include "population.hpp" ian@0: #include "program_options.hpp" ian@0: #include "sc_converter.hpp" ian@0: #include "sc_default_grammar.hpp" ian@0: #include "sc_evaluator.hpp" ian@0: #include "sc_grammar.hpp" ian@0: ian@0: #include "boost/filesystem.hpp" ian@0: #include "boost/shared_array.hpp" ian@0: ian@0: #include ian@0: #include ian@0: #include ian@0: #include ian@0: #include ian@0: ian@0: const std::string g_test_grammar_path = "/tmp/sc.json"; ian@0: ian@0: template ian@0: void SaveToFile(const T& value, const std::string& file_path) { ian@0: std::ofstream file(file_path.c_str()); ian@0: file << value; ian@0: } ian@0: ian@0: void TestCrossover() { ian@0: sc::Grammar grammar(g_test_grammar_path); ian@0: sc::Converter converter(grammar); ian@0: sg::Graph parent_1; ian@0: sg::Graph parent_2; ian@0: grammar.SetMaximumDepth(2); ian@0: grammar.RandomGraph(parent_1); ian@0: grammar.RandomGraph(parent_2); ian@0: sg::Vertex crossover_1; ian@0: sg::Vertex crossover_2; ian@0: grammar.PickCrossoverNodes(parent_1, parent_2, &crossover_1, &crossover_2); ian@0: // swap the subtrees ian@0: sg::Graph child_1; ian@0: sg::Graph child_2; ian@0: SwapSubTrees(crossover_1, crossover_2, parent_1, parent_2, child_1, child_2); ian@0: SaveToFile(converter.ToDOT(parent_1), "/tmp/parent1.dot"); ian@0: SaveToFile(converter.ToDOT(parent_2), "/tmp/parent2.dot"); ian@0: SaveToFile(converter.ToDOT(child_1), "/tmp/child1.dot"); ian@0: SaveToFile(converter.ToDOT(child_2), "/tmp/child2.dot"); ian@0: } ian@0: ian@0: void TestMutationReplaceSubtree() { ian@0: sc::Grammar grammar(g_test_grammar_path); ian@0: sc::Converter converter(grammar); ian@0: sg::Graph graph; ian@0: grammar.RandomGraph(graph); ian@0: SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_before.dot"); ian@0: grammar.MutationReplaceSubTree(graph); ian@0: SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_after.dot"); ian@0: } ian@0: ian@0: void TestMutationReplaceCommand() { ian@0: sc::Grammar grammar(g_test_grammar_path); ian@0: sc::Converter converter(grammar); ian@0: sg::Graph graph; ian@0: grammar.SetMaximumDepth(3); ian@0: grammar.RandomGraph(graph); ian@0: SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_before.dot"); ian@0: SaveToFile(converter.ToSynthDef(graph, "before"), ian@0: "/tmp/mutation_str_before.sc"); ian@0: grammar.MutationReplaceCommand(graph); ian@0: SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_after.dot"); ian@0: SaveToFile(converter.ToSynthDef(graph, "after"), ian@0: "/tmp/mutation_str_after.sc"); ian@0: } ian@0: ian@0: void TestMutationInsertCommand() { ian@0: sc::Grammar grammar(g_test_grammar_path); ian@0: sc::Converter converter(grammar); ian@0: sg::Graph graph; ian@0: grammar.SetMaximumDepth(4); ian@0: grammar.RandomGraph(graph); ian@0: SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_before.dot"); ian@0: SaveToFile(converter.ToSynthDef(graph, "before"), ian@0: "/tmp/mutation_str_before.sc"); ian@0: grammar.MutationInsertCommand(graph); ian@0: SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_after.dot"); ian@0: SaveToFile(converter.ToSynthDef(graph, "after"), ian@0: "/tmp/mutation_str_after.sc"); ian@0: } ian@0: ian@0: void DoEvolution(const ProgramOptions& settings) { ian@0: // prepare the file comparer ian@0: dsp::FileComparer target(settings.fitness_features_, ian@0: static_cast(settings.analysis_window_size_), ian@0: static_cast(settings.analysis_hop_size_)); ian@0: target.SetTargetFile(settings.target_path_); ian@0: // prepare the supercollider objects ian@0: std::string grammar_json; ian@0: if (settings.grammar_path_.empty()) { ian@0: grammar_json.assign(sc::g_default_grammar); ian@0: } else { ian@0: grammar_json = stdx::LoadFile(settings.grammar_path_); ian@0: } ian@0: sc::Grammar grammar(grammar_json); ian@0: grammar.SetMaximumDepth(static_cast(settings.maximum_tree_depth_)); ian@0: sc::Evaluator evaluator(grammar, ian@0: settings.sc_app_path_, ian@0: target, ian@0: static_cast(settings.core_limit_)); ian@0: sc::Converter converter(grammar); ian@0: // set up the population ian@0: Population population(&grammar, &converter, &evaluator); ian@0: population.SetWorkFolder(settings.work_folder_); ian@0: population.SetFitnessThreshold(settings.fitness_threshold_); ian@0: population.SetCrossoverRate(settings.crossover_rate_); ian@0: population.SetMutationRate(settings.mutation_rate_); ian@0: population.SetTournamentSize(static_cast(settings.tournament_size_)); ian@0: population.SetReproduceBest(settings.reproduce_best_individual_); ian@0: population.InitializePopulation(settings.population_size_); ian@0: population.SetKeepTempFolders(settings.keep_temp_folders_); ian@0: // run the evolution loop ian@0: population.Evolve(static_cast(settings.generations_)); ian@0: } ian@0: ian@0: int main(int argument_count, const char* arguments[]) ian@0: { ian@0: srand(static_cast(time(NULL))); ian@0: try { ian@0: // parse the command line options ian@0: ProgramOptions settings; ian@0: ParseCommandLine(argument_count, arguments, &settings); ian@0: DoEvolution(settings); ian@0: ian@0: //TestCrossover(); ian@0: //TestMutationReplaceSubtree(); ian@0: //TestMutationInsertCommand(); ian@0: //TestMutationReplaceCommand(); ian@0: } catch (const std::exception& e) { ian@0: std::stringstream message; ian@0: message << "Exception: " << e.what() << '\n'; ian@0: logger::Log(message.str()); ian@0: logger::Flush(); ian@0: return -1; ian@0: } ian@0: logger::Flush(); ian@0: }