43 std::vector<int> input_ids;
44 std::vector<int> output_ids;
46 for (
const auto& n : genome.
nodes()) {
49 input_ids.push_back(n.id);
55 output_ids.push_back(n.id);
61 std::sort(input_ids.begin(), input_ids.end());
62 std::sort(output_ids.begin(), output_ids.end());
64 if (inputs.size() != input_ids.size()) {
65 throw std::invalid_argument(
"EvaluateNEATPhenotype: inputs.size() must match the genome's Input node count");
68 std::map<int, double> fixed_values;
69 for (
size_t i = 0; i < input_ids.size(); ++i) {
70 fixed_values[input_ids[i]] = inputs[i];
73 fixed_values[bias_id] = 1.0;
76 std::map<int, double> cache;
77 std::function<double(
int)> evaluate = [&](
int node_id) ->
double {
78 auto fixed_it = fixed_values.find(node_id);
79 if (fixed_it != fixed_values.end()) {
80 return fixed_it->second;
82 auto cached_it = cache.find(node_id);
83 if (cached_it != cache.end()) {
84 return cached_it->second;
88 if (c.enabled && c.out_node == node_id) {
89 sum += c.weight * evaluate(c.in_node);
92 double activated = 1.0 / (1.0 + std::exp(-4.9 * sum));
93 cache[node_id] = activated;
97 std::vector<double> outputs;
98 outputs.reserve(output_ids.size());
99 for (
int id : output_ids) {
100 outputs.push_back(evaluate(
id));
std::vector< double > EvaluateNEATPhenotype(const NEATGenome &genome, const std::vector< double > &inputs)
Evaluates genome's phenotype forward pass on inputs (one value per Input node, ordered by ascending n...
Definition neat_phenotype.hpp:42