1 /**************************************************************************/ 2 /* Copyright 2012 Tim Day */ 3 /* */ 4 /* This file is part of Evolvotron */ 5 /* */ 6 /* Evolvotron is free software: you can redistribute it and/or modify */ 7 /* it under the terms of the GNU General Public License as published by */ 8 /* the Free Software Foundation, either version 3 of the License, or */ 9 /* (at your option) any later version. */ 10 /* */ 11 /* Evolvotron is distributed in the hope that it will be useful, */ 12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 14 /* GNU General Public License for more details. */ 15 /* */ 16 /* You should have received a copy of the GNU General Public License */ 17 /* along with Evolvotron. If not, see <http://www.gnu.org/licenses/>. */ 18 /**************************************************************************/ 19 20 /*! \file 21 \brief Interface for class MutationParameters. 22 */ 23 24 #ifndef _mutation_parameters_h_ 25 #define _mutation_parameters_h_ 26 27 #include "common.h" 28 #include "random.h" 29 30 class FunctionNode; 31 class FunctionRegistration; 32 class FunctionRegistry; 33 34 //! Class encapsulating mutation parameters. 35 /*! For example, magnitude of variations, probability of leaves being dropped. 36 Also provides a random number generator. 37 */ 38 class MutationParameters 39 { 40 private: 41 42 const std::unique_ptr<FunctionRegistry> _function_registry; 43 44 protected: 45 46 //! A random number generator. 47 /*! Declared mutable so we can pass const MutationParameters& around and still do useful work with it. 48 */ 49 mutable Random01 _r01; 50 51 //! Negative-exponential generator might be useful too. 52 mutable RandomNegExp _r_negexp; 53 54 //! Specifies the base magnitude of random changes the function parameters. 55 real _base_magnitude_parameter_variation; 56 57 //! Specifies the base probability of a the parameter set being completely reset. 58 real _base_probability_parameter_reset; 59 60 //! Specifies the base probability of a child being dropped and replaced with a new random stub. 61 real _base_probability_glitch; 62 63 //! Specifies the base probability of all child nodes being reordered. 64 real _base_probability_shuffle; 65 66 //! Specifies the base probability of a random stub being inserted before a child. 67 real _base_probability_insert; 68 69 //! Specifies the base probability of a node being replaced with an alternate type. 70 real _base_probability_substitute; 71 72 //! Specifies the proportion of basic node types. 73 real _proportion_basic; 74 75 //! Specifies the proportion of Constant nodes vs Position type nodes. 76 real _proportion_constant; 77 78 //! Specifies the probability of a using a FunctionNodePositionTransformed instead of FunctionNodePosition 79 real _identity_supression; 80 81 //! The maximum number of iterations an iterative function node can have initially. 82 uint _max_initial_iterations; 83 84 //! The base probability of the number of iterations changing by plus or minus 1. 85 real _base_probability_iterations_change_step; 86 87 //! The base probability of the number of iterations changing by times or divide 2. 88 real _base_probability_iterations_change_jump; 89 90 //! Individual weighting modifiers for each function type 91 /*! Will only be applied to random functions we're asked for. 92 The bulk of nodes are created by FunctionNode and are boring to keep the branching ratio down. 93 \todo Implement a branching ratio query method. 94 */ 95 std::map<const FunctionRegistration*,real> _function_weighting; 96 97 //! Total of function weights, for normalisation. 98 real _function_weighting_total; 99 100 //! Map from [0,1] to a function registration, taking weights into account. 101 std::map<real,const FunctionRegistration*> _function_pick; 102 103 //! What state a reset should return autocool to. 104 const bool _autocool_reset_state; 105 106 //! Whether autocooling is being applied. 107 bool _autocool_enable; 108 109 //! Number of generations at which parameters will be half cooled. 110 uint _autocool_halflife; 111 112 //! Count of number of generations for decay cooling. 113 uint _autocool_generations; 114 115 //! Just use SingleChannelNoise for almost all functions (useful for debugging). 116 const bool _debug_mode; 117 118 void recalculate_function_stuff(); 119 120 public: 121 //! Trivial constructor. 122 MutationParameters(uint seed,bool ac,bool debug_mode); 123 124 //! Trivial destructor. 125 virtual ~MutationParameters(); 126 127 //! Accessor. function_registry()128 const FunctionRegistry& function_registry() const 129 { 130 return *_function_registry; 131 } 132 133 //! Reset to initial values. 134 void reset(); 135 136 //! Multiply most parameters by the given factor 137 void general_cool(real f); 138 139 //! Returns a reference to the random number generator. 140 /*! Need this for e.g RandomXYZInSphere constructor. 141 */ rng01()142 Random01& rng01() const 143 { 144 return _r01; 145 } 146 147 //! Return a number in the range [0,1) r01()148 real r01() const 149 { 150 return _r01(); 151 } 152 rnegexp()153 real rnegexp() const 154 { 155 return _r_negexp(); 156 } 157 158 //! Accessor, with decay. effective_magnitude_parameter_variation()159 real effective_magnitude_parameter_variation() const 160 { 161 return base_magnitude_parameter_variation()*decay_factor(); 162 } 163 //! Accessor. base_magnitude_parameter_variation()164 real base_magnitude_parameter_variation() const 165 { 166 return _base_magnitude_parameter_variation; 167 } 168 //! Accessor. base_magnitude_parameter_variation(real v)169 void base_magnitude_parameter_variation(real v) 170 { 171 _base_magnitude_parameter_variation=v; 172 report_change(); 173 } 174 175 //! Accessor, with decay. effective_probability_parameter_reset()176 real effective_probability_parameter_reset() const 177 { 178 return base_probability_parameter_reset()*decay_factor(); 179 } 180 //! Accessor. base_probability_parameter_reset()181 real base_probability_parameter_reset() const 182 { 183 return _base_probability_parameter_reset; 184 } 185 //! Accessor. base_probability_parameter_reset(real v)186 void base_probability_parameter_reset(real v) 187 { 188 _base_probability_parameter_reset=v; 189 report_change(); 190 } 191 192 //! Accessor, with decay. effective_probability_glitch()193 real effective_probability_glitch() const 194 { 195 return base_probability_glitch()*decay_factor(); 196 } 197 //! Accessor. base_probability_glitch()198 real base_probability_glitch() const 199 { 200 return _base_probability_glitch; 201 } 202 //! Accessor. base_probability_glitch(real v)203 void base_probability_glitch(real v) 204 { 205 _base_probability_glitch=v; 206 report_change(); 207 } 208 209 //! Accessor, with decay. effective_probability_shuffle()210 real effective_probability_shuffle() const 211 { 212 return base_probability_shuffle()*decay_factor(); 213 } 214 //! Accessor. base_probability_shuffle()215 real base_probability_shuffle() const 216 { 217 return _base_probability_shuffle; 218 } 219 //! Accessor. base_probability_shuffle(real v)220 void base_probability_shuffle(real v) 221 { 222 _base_probability_shuffle=v; 223 report_change(); 224 } 225 226 //! Accessor, with decay. effective_probability_insert()227 real effective_probability_insert() const 228 { 229 return base_probability_insert()*decay_factor(); 230 } 231 //! Accessor. base_probability_insert()232 real base_probability_insert() const 233 { 234 return _base_probability_insert; 235 } 236 //! Accessor. base_probability_insert(real v)237 void base_probability_insert(real v) 238 { 239 _base_probability_insert=v; 240 report_change(); 241 } 242 243 //! Accessor. effective_probability_substitute()244 real effective_probability_substitute() const 245 { 246 return base_probability_substitute()*decay_factor(); 247 } 248 //! Accessor. base_probability_substitute()249 real base_probability_substitute() const 250 { 251 return _base_probability_substitute; 252 } 253 //! Accessor. base_probability_substitute(real v)254 void base_probability_substitute(real v) 255 { 256 _base_probability_substitute=v; 257 report_change(); 258 } 259 260 //! Accessor. proportion_constant()261 real proportion_constant() const 262 { 263 return _proportion_constant; 264 } 265 //! Accessor. proportion_constant(real v)266 void proportion_constant(real v) 267 { 268 _proportion_constant=v; 269 report_change(); 270 } 271 272 //! Accessor. identity_supression()273 real identity_supression() const 274 { 275 return _identity_supression; 276 } 277 //! Accessor. identity_supression(real v)278 void identity_supression(real v) 279 { 280 _identity_supression=v; 281 report_change(); 282 } 283 284 //! Accessor. max_initial_iterations()285 uint max_initial_iterations() const 286 { 287 return _max_initial_iterations; 288 } 289 //! Accessor. max_initial_iterations(uint v)290 void max_initial_iterations(uint v) 291 { 292 _max_initial_iterations=v; 293 report_change(); 294 } 295 296 //! Accessor, with decay. effective_probability_iterations_change_step()297 real effective_probability_iterations_change_step() const 298 { 299 return base_probability_iterations_change_step()*decay_factor(); 300 } 301 //! Accessor. base_probability_iterations_change_step()302 real base_probability_iterations_change_step() const 303 { 304 return _base_probability_iterations_change_step; 305 } 306 //! Accessor. base_probability_iterations_change_step(real v)307 void base_probability_iterations_change_step(real v) 308 { 309 _base_probability_iterations_change_step=v; 310 report_change(); 311 } 312 313 //! Accessor, with decay. effective_probability_iterations_change_jump()314 real effective_probability_iterations_change_jump() const 315 { 316 return base_probability_iterations_change_jump()*decay_factor(); 317 } 318 //! Accessor. base_probability_iterations_change_jump()319 real base_probability_iterations_change_jump() const 320 { 321 return _base_probability_iterations_change_jump; 322 } 323 //! Accessor. base_probability_iterations_change_jump(real v)324 void base_probability_iterations_change_jump(real v) 325 { 326 _base_probability_iterations_change_jump=v; 327 report_change(); 328 } 329 330 //! Accessor. proportion_basic()331 real proportion_basic() const 332 { 333 return _proportion_basic; 334 } 335 //! Accessor. proportion_basic(real p)336 void proportion_basic(real p) 337 { 338 _proportion_basic=p; 339 report_change(); 340 } 341 342 //! Accessor. autocool_enable()343 bool autocool_enable() const 344 { 345 return _autocool_enable; 346 } 347 //! Accessor. autocool_enable(bool v)348 void autocool_enable(bool v) 349 { 350 _autocool_enable=v; 351 std::clog << "Autocooling " << (autocool_enable() ? "ON" : "OFF") << "\n"; 352 report_change(); 353 } 354 355 //! Accessor. autocool_halflife()356 int autocool_halflife() const 357 { 358 return _autocool_halflife; 359 } 360 //! Accessor. autocool_halflife(int v)361 void autocool_halflife(int v) 362 { 363 _autocool_halflife=v; 364 report_change(); 365 } 366 367 //! Accessor autocool_generations()368 int autocool_generations() const 369 { 370 return _autocool_generations; 371 } 372 //! Accessor. autocool_generations(int v)373 void autocool_generations(int v) 374 { 375 _autocool_generations=v; 376 report_change(); 377 } 378 //! Accessor. autocool_generations_increment()379 void autocool_generations_increment() 380 { 381 _autocool_generations++; 382 report_change(); 383 } 384 385 //! Calculate branching ratio for above calls 386 /* Call user should be checking this and diluting with boring nodes to keep it under control 387 */ 388 real random_function_branching_ratio() const; 389 390 //! This returns a new random bit of tree. 391 /*! Setting the "exciting" flag avoids the most basic node types, but only at the top level of the stub tree. 392 */ 393 std::unique_ptr<FunctionNode> random_function_stub(bool exciting) const; 394 395 void change_function_weighting(const FunctionRegistration* fn,real w); 396 397 void randomize_function_weightings_for_classifications(uint classification_mask); 398 399 real get_weighting(const FunctionRegistration* fn); 400 401 protected: 402 403 //! Compute current decay factor 404 real decay_factor() const; 405 406 //! Return a random function appropriately biased by current settings 407 std::unique_ptr<FunctionNode> random_function() const; 408 409 //! Return a random function registration, appropriately biased by current settings 410 const FunctionRegistration* random_weighted_function_registration() const; 411 412 //! Intended for Qt-world subclass to override to emit signal. 413 virtual void report_change(); 414 }; 415 416 #endif 417