Vita
evaluator.tcc
1/**
2 * \file
3 * \remark This file is part of VITA.
4 *
5 * \copyright Copyright (C) 2012-2023 EOS di Manlio Morini.
6 *
7 * \license
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
10 * You can obtain one at http://mozilla.org/MPL/2.0/
11 */
12
13#if !defined(VITA_EVALUATOR_H)
14# error "Don't include this file directly, include the specific .h instead"
15#endif
16
17#if !defined(VITA_EVALUATOR_TCC)
18#define VITA_EVALUATOR_TCC
19
20///
21/// An approximate, faster version of the standard evaluator.
22///
23/// \param[in] i an individual to be evaluated
24/// \return the fitness (usually an approximation of) `i`
25///
26/// Some evaluators have a faster but approximated version of the standard
27/// fitness evaluation method.
28///
29/// \note Default implementation calls the standard fitness function.
30///
31template<class T>
32fitness_t evaluator<T>::fast(const T &i)
33{
34 return operator()(i);
35}
36
37///
38/// \param[in] in input stream
39/// \return `true` if the object loaded correctly
40///
41/// \note
42/// If the load operation isn't successful the current object isn't changed.
43///
44template<class T>
45bool evaluator<T>::load([[maybe_unused]] std::istream &in)
46{
47 return true;
48}
49
50///
51/// \param[out] out output stream
52/// \return `true` if the object was saved correctly
53///
54template<class T>
55bool evaluator<T>::save([[maybe_unused]] std::ostream &out) const
56{
57 return true;
58}
59
60///
61/// Derived methods create the 'executable' form of an individual.
62///
63/// \return `nullptr`
64///
65/// The default implementation is an empty method.
66///
67template<class T>
68std::unique_ptr<basic_lambda_f> evaluator<T>::lambdify(const T &) const
69{
70 return nullptr;
71}
72
73template<class T>
74test_evaluator<T>::test_evaluator(test_evaluator_type et) : buffer_(), et_(et)
75{
76}
77
78///
79/// \param[in] prg a program (individual/team)
80/// \return fitness value for individual `prg`
81///
82/// Depending on the type of test_evaluator returns:
83/// - a random, time-invariant fitness value for `prg`;
84/// - a fixed, time-invariant fitness value for every individual of the
85/// population;
86/// - a distinct, time-invariant fitness value for each `prg`.
87///
88template<class T>
89fitness_t test_evaluator<T>::operator()(const T &prg)
90{
91 if (et_ == test_evaluator_type::fixed)
92 return {static_cast<fitness_t::value_type>(0)};
93
94 auto it(std::find(buffer_.begin(), buffer_.end(), prg));
95 if (it == buffer_.end())
96 {
97 buffer_.push_back(prg);
98 it = std::prev(buffer_.end());
99 }
100
101 const auto dist(std::distance(buffer_.begin(), it));
102
103 if (et_ == test_evaluator_type::distinct)
104 return {static_cast<fitness_t::value_type>(dist)};
105
106 assert(et_ == test_evaluator_type::random);
107 static random::engine_t e;
108 e.seed(dist);
109 return {static_cast<fitness_t::value_type>(e())};
110}
111
112#endif // include guard