Darwin Neuroevolution Framework
max.h
1 // Copyright 2018 The Darwin Neuroevolution Framework Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include "robot.h"
18 #include "world.h"
19 
20 #include <core/darwin.h>
21 #include <core/evolution.h>
22 #include <core/logging.h>
23 #include <core/parallel_for_each.h>
24 
25 using core::log;
26 
27 namespace find_max_value {
28 
65 class FindMaxValue : public darwin::Domain {
66  public:
67  size_t inputs() const override { return Robot::kInputs; }
68  size_t outputs() const override { return Robot::kOutputs; }
69 
70  bool evaluatePopulation(darwin::Population* population) const override {
71  darwin::StageScope stage("Evaluate population");
72 
73  const int generation = population->generation();
74  log("\n. generation %d\n", generation);
75 
76  // generate test worlds
77  vector<World> worlds(g_config.test_worlds);
78  pp::for_each(worlds, [&](int, World& world) { world.generate(); });
79 
80  // "grow" robots from each genotype in the population
81  vector<Robot> robots(population->size());
82 
83  {
84  darwin::StageScope stage("Ontogenesis");
85  pp::for_each(robots, [&](int index, Robot& robot) {
86  auto genotype = population->genotype(index);
87  robot.grow(genotype);
88  genotype->fitness = 0;
89  });
90  }
91 
92  // evaluate the robots in each test world
93  {
94  darwin::StageScope stage("Evaluate multiple worlds", worlds.size());
95  for (int world_index = 0; world_index < worlds.size(); ++world_index) {
96  log(" ... world %d\n", world_index);
97  const World& world_template = worlds[world_index];
98 
99  {
100  darwin::StageScope stage("Evaluate one world", robots.size());
101  pp::for_each(robots, [&](int robot_index, Robot& robot) {
102  World sandbox;
103  sandbox.simInit(world_template, &robot);
104 
105  while (robot.alive())
106  sandbox.simStep();
107 
108  population->genotype(robot_index)->fitness += robot.fitness / worlds.size();
109 
111  });
112  }
113 
115  }
116  }
117 
118  log("\n");
119  return false;
120  }
121 };
122 
123 class Factory : public darwin::DomainFactory {
124  unique_ptr<darwin::Domain> create(const core::PropertySet& config) override {
125  g_config.copyFrom(config);
126  return make_unique<FindMaxValue>();
127  }
128 
129  unique_ptr<core::PropertySet> defaultConfig(
130  darwin::ComplexityHint hint) const override {
131  auto config = make_unique<Config>();
132  switch (hint) {
134  config->test_worlds = 2;
135  config->min_size = kMinSize;
136  config->max_size = 10;
137  break;
138 
140  break;
141 
143  config->test_worlds = 30;
144  config->min_size = kMinSize;
145  config->max_size = 250;
146  break;
147  }
148  return config;
149  }
150 };
151 
152 inline void init() {
153  darwin::registry()->domains.add<Factory>("find_max_value");
154 }
155 
156 } // namespace find_max_value
void log(const char *format_string, ARGS &&... args)
Outputs a formatted log message.
Definition: logging.h:45
virtual size_t size() const =0
The fixed number of genotypes in the population.
ComplexityHint
A generic hint for the initial population & domain setup.
Definition: darwin.h:47
A population implementation encapsulates the fixed-size set of genotypes, together with the rules for...
Definition: darwin.h:161
best guess for the ideal performance/results trade-offs
virtual Genotype * genotype(size_t index)=0
Indexed access to a genotype in the population.
virtual unique_ptr< Brain > grow() const =0
"Grow" a Brain using the genetic "recipe" encoded in this genotype
Registry * registry()
Accessor to the Registry singleton.
Definition: darwin.h:295
virtual int generation() const =0
The current generation number.
bare minimum, fast but poor results (mostly useful for testing)
float fitness
The evaluated fitness value (see Domain::evaluatePopulation)
Definition: darwin.h:129
A scope-based Stage wrapper.
Definition: evolution.h:442
static void reportProgress(size_t increment=1)
Reports stage progress.
Definition: evolution.h:267
Interface to the domain factory.
Definition: darwin.h:263
Domain: Locate the maximum value in an array.
Definition: max.h:65
might produce more sophisticated solutions, but very slow
size_t inputs() const override
Number of inputs to a Brain.
Definition: max.h:67
Definition: max.h:27
void for_each(T &array, const Body &loop_body)
Iterates over an array, with support for parallel execution.
Definition: parallel_for_each.h:55
void copyFrom(const PropertySet &src)
Transfer values between two property sets.
Definition: properties.h:416
The foundation for data structures supporting runtime reflection.
Definition: properties.h:388
bool evaluatePopulation(darwin::Population *population) const override
Assigns fitness values to every genotype.
Definition: max.h:70
core::ImplementationsSet< DomainFactory > domains
Registered domains.
Definition: darwin.h:288
Interface to a domain implementation.
Definition: darwin.h:229
size_t outputs() const override
Number of outputs from a Brain.
Definition: max.h:68