ian@0
|
1 // Copyright 2011, Ian Hobson.
|
ian@0
|
2 //
|
ian@0
|
3 // This file is part of gpsynth.
|
ian@0
|
4 //
|
ian@0
|
5 // gpsynth is free software: you can redistribute it and/or modify
|
ian@0
|
6 // it under the terms of the GNU General Public License as published by
|
ian@0
|
7 // the Free Software Foundation, either version 3 of the License, or
|
ian@0
|
8 // (at your option) any later version.
|
ian@0
|
9 //
|
ian@0
|
10 // gpsynth is distributed in the hope that it will be useful,
|
ian@0
|
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
ian@0
|
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
ian@0
|
13 // GNU General Public License for more details.
|
ian@0
|
14 //
|
ian@0
|
15 // You should have received a copy of the GNU General Public License
|
ian@0
|
16 // along with gpsynth in the file COPYING.
|
ian@0
|
17 // If not, see http://www.gnu.org/licenses/.
|
ian@0
|
18
|
ian@0
|
19 #include "file_comparer.hpp"
|
ian@0
|
20 #include "graph_helpers.hpp"
|
ian@0
|
21 #include "logger.hpp"
|
ian@0
|
22 #include "population.hpp"
|
ian@0
|
23 #include "program_options.hpp"
|
ian@0
|
24 #include "sc_converter.hpp"
|
ian@0
|
25 #include "sc_default_grammar.hpp"
|
ian@0
|
26 #include "sc_evaluator.hpp"
|
ian@0
|
27 #include "sc_grammar.hpp"
|
ian@0
|
28
|
ian@0
|
29 #include "boost/filesystem.hpp"
|
ian@0
|
30 #include "boost/shared_array.hpp"
|
ian@0
|
31
|
ian@0
|
32 #include <algorithm>
|
ian@0
|
33 #include <ctime>
|
ian@0
|
34 #include <fstream>
|
ian@0
|
35 #include <iostream>
|
ian@0
|
36 #include <sstream>
|
ian@0
|
37
|
ian@0
|
38 const std::string g_test_grammar_path = "/tmp/sc.json";
|
ian@0
|
39
|
ian@0
|
40 template<typename T>
|
ian@0
|
41 void SaveToFile(const T& value, const std::string& file_path) {
|
ian@0
|
42 std::ofstream file(file_path.c_str());
|
ian@0
|
43 file << value;
|
ian@0
|
44 }
|
ian@0
|
45
|
ian@0
|
46 void TestCrossover() {
|
ian@0
|
47 sc::Grammar grammar(g_test_grammar_path);
|
ian@0
|
48 sc::Converter converter(grammar);
|
ian@0
|
49 sg::Graph parent_1;
|
ian@0
|
50 sg::Graph parent_2;
|
ian@0
|
51 grammar.SetMaximumDepth(2);
|
ian@0
|
52 grammar.RandomGraph(parent_1);
|
ian@0
|
53 grammar.RandomGraph(parent_2);
|
ian@0
|
54 sg::Vertex crossover_1;
|
ian@0
|
55 sg::Vertex crossover_2;
|
ian@0
|
56 grammar.PickCrossoverNodes(parent_1, parent_2, &crossover_1, &crossover_2);
|
ian@0
|
57 // swap the subtrees
|
ian@0
|
58 sg::Graph child_1;
|
ian@0
|
59 sg::Graph child_2;
|
ian@0
|
60 SwapSubTrees(crossover_1, crossover_2, parent_1, parent_2, child_1, child_2);
|
ian@0
|
61 SaveToFile(converter.ToDOT(parent_1), "/tmp/parent1.dot");
|
ian@0
|
62 SaveToFile(converter.ToDOT(parent_2), "/tmp/parent2.dot");
|
ian@0
|
63 SaveToFile(converter.ToDOT(child_1), "/tmp/child1.dot");
|
ian@0
|
64 SaveToFile(converter.ToDOT(child_2), "/tmp/child2.dot");
|
ian@0
|
65 }
|
ian@0
|
66
|
ian@0
|
67 void TestMutationReplaceSubtree() {
|
ian@0
|
68 sc::Grammar grammar(g_test_grammar_path);
|
ian@0
|
69 sc::Converter converter(grammar);
|
ian@0
|
70 sg::Graph graph;
|
ian@0
|
71 grammar.RandomGraph(graph);
|
ian@0
|
72 SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_before.dot");
|
ian@0
|
73 grammar.MutationReplaceSubTree(graph);
|
ian@0
|
74 SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_after.dot");
|
ian@0
|
75 }
|
ian@0
|
76
|
ian@0
|
77 void TestMutationReplaceCommand() {
|
ian@0
|
78 sc::Grammar grammar(g_test_grammar_path);
|
ian@0
|
79 sc::Converter converter(grammar);
|
ian@0
|
80 sg::Graph graph;
|
ian@0
|
81 grammar.SetMaximumDepth(3);
|
ian@0
|
82 grammar.RandomGraph(graph);
|
ian@0
|
83 SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_before.dot");
|
ian@0
|
84 SaveToFile(converter.ToSynthDef(graph, "before"),
|
ian@0
|
85 "/tmp/mutation_str_before.sc");
|
ian@0
|
86 grammar.MutationReplaceCommand(graph);
|
ian@0
|
87 SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_after.dot");
|
ian@0
|
88 SaveToFile(converter.ToSynthDef(graph, "after"),
|
ian@0
|
89 "/tmp/mutation_str_after.sc");
|
ian@0
|
90 }
|
ian@0
|
91
|
ian@0
|
92 void TestMutationInsertCommand() {
|
ian@0
|
93 sc::Grammar grammar(g_test_grammar_path);
|
ian@0
|
94 sc::Converter converter(grammar);
|
ian@0
|
95 sg::Graph graph;
|
ian@0
|
96 grammar.SetMaximumDepth(4);
|
ian@0
|
97 grammar.RandomGraph(graph);
|
ian@0
|
98 SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_before.dot");
|
ian@0
|
99 SaveToFile(converter.ToSynthDef(graph, "before"),
|
ian@0
|
100 "/tmp/mutation_str_before.sc");
|
ian@0
|
101 grammar.MutationInsertCommand(graph);
|
ian@0
|
102 SaveToFile(converter.ToDOT(graph), "/tmp/mutation_str_after.dot");
|
ian@0
|
103 SaveToFile(converter.ToSynthDef(graph, "after"),
|
ian@0
|
104 "/tmp/mutation_str_after.sc");
|
ian@0
|
105 }
|
ian@0
|
106
|
ian@0
|
107 void DoEvolution(const ProgramOptions& settings) {
|
ian@0
|
108 // prepare the file comparer
|
ian@0
|
109 dsp::FileComparer target(settings.fitness_features_,
|
ian@0
|
110 static_cast<int>(settings.analysis_window_size_),
|
ian@0
|
111 static_cast<int>(settings.analysis_hop_size_));
|
ian@0
|
112 target.SetTargetFile(settings.target_path_);
|
ian@0
|
113 // prepare the supercollider objects
|
ian@0
|
114 std::string grammar_json;
|
ian@0
|
115 if (settings.grammar_path_.empty()) {
|
ian@0
|
116 grammar_json.assign(sc::g_default_grammar);
|
ian@0
|
117 } else {
|
ian@0
|
118 grammar_json = stdx::LoadFile(settings.grammar_path_);
|
ian@0
|
119 }
|
ian@0
|
120 sc::Grammar grammar(grammar_json);
|
ian@0
|
121 grammar.SetMaximumDepth(static_cast<int>(settings.maximum_tree_depth_));
|
ian@0
|
122 sc::Evaluator evaluator(grammar,
|
ian@0
|
123 settings.sc_app_path_,
|
ian@0
|
124 target,
|
ian@0
|
125 static_cast<int>(settings.core_limit_));
|
ian@0
|
126 sc::Converter converter(grammar);
|
ian@0
|
127 // set up the population
|
ian@0
|
128 Population population(&grammar, &converter, &evaluator);
|
ian@0
|
129 population.SetWorkFolder(settings.work_folder_);
|
ian@0
|
130 population.SetFitnessThreshold(settings.fitness_threshold_);
|
ian@0
|
131 population.SetCrossoverRate(settings.crossover_rate_);
|
ian@0
|
132 population.SetMutationRate(settings.mutation_rate_);
|
ian@0
|
133 population.SetTournamentSize(static_cast<int>(settings.tournament_size_));
|
ian@0
|
134 population.SetReproduceBest(settings.reproduce_best_individual_);
|
ian@0
|
135 population.InitializePopulation(settings.population_size_);
|
ian@0
|
136 population.SetKeepTempFolders(settings.keep_temp_folders_);
|
ian@0
|
137 // run the evolution loop
|
ian@0
|
138 population.Evolve(static_cast<int>(settings.generations_));
|
ian@0
|
139 }
|
ian@0
|
140
|
ian@0
|
141 int main(int argument_count, const char* arguments[])
|
ian@0
|
142 {
|
ian@0
|
143 srand(static_cast<unsigned int>(time(NULL)));
|
ian@0
|
144 try {
|
ian@0
|
145 // parse the command line options
|
ian@0
|
146 ProgramOptions settings;
|
ian@0
|
147 ParseCommandLine(argument_count, arguments, &settings);
|
ian@0
|
148 DoEvolution(settings);
|
ian@0
|
149
|
ian@0
|
150 //TestCrossover();
|
ian@0
|
151 //TestMutationReplaceSubtree();
|
ian@0
|
152 //TestMutationInsertCommand();
|
ian@0
|
153 //TestMutationReplaceCommand();
|
ian@0
|
154 } catch (const std::exception& e) {
|
ian@0
|
155 std::stringstream message;
|
ian@0
|
156 message << "Exception: " << e.what() << '\n';
|
ian@0
|
157 logger::Log(message.str());
|
ian@0
|
158 logger::Flush();
|
ian@0
|
159 return -1;
|
ian@0
|
160 }
|
ian@0
|
161 logger::Flush();
|
ian@0
|
162 }
|