symbolic_regression_part3 - morinim/vita GitHub Wiki
A custom evaluator is nice but not enough. What I really need is a way to evolve multiple programs at the same time and then apply my evaluator. Can it be done?
Yes, it can. You can use a team.
This is similar to the previous problem but requires the evolution of multiple candidate solutions at the same time.
const auto a = get_vector(); // N-dimensional vector
const auto b = get_matrix(); // NxN matrix
This time a
and b
aren't scalar. We use two support functions to generate a random vector and a random matrix of the appropriate dimensions.
Once again the evaluator needs various remarks:
using candidate_solution = vita::team<vita::i_mep>;
class my_evaluator : public vita::evaluator<candidate_solution>
{
public:
vita::fitness_t operator()(const candidate_solution &x) override
{
std::vector<double> f(N);
std::transform(x.begin(), x.end(), f.begin(),
[](const auto &prg)
{
const auto ret(vita::run(prg));
return vita::has_value(ret) ? std::get<vita::D_DOUBLE>(ret)
: 0.0;
});
std::vector<double> model(N, 0.0);
for (unsigned i(0); i < N; ++i)
for (unsigned j(0); j < N; ++j)
model[i] += b(i, j) * f[j];
double delta(std::inner_product(a.begin(), a.end(), model.begin(), 0.0,
std::plus<>(),
[](auto v1, auto v2)
{
return std::fabs(v1 - v2);
}));
return {-delta};
}
};
The candidate_solution
is a team of individuals/programs. The members of a team undergo a coevolutionary process because they are always selected, evaluated and varied simultaneously.
A line by line description of the evaluation process follows:
std::vector<double> f(N);
std::transform(x.begin(), x.end(), f.begin(),
[](const auto &prg)
{
const auto ret(vita::run(prg));
return vita::has_value(ret) ? std::get<vita::D_DOUBLE>(ret)
: 0.0;
});
This time f
is a vector (where we store the results of the components of the team/candidate_solution).
std::vector<double> model(N, 0.0);
for (unsigned i(0); i < N; ++i)
for (unsigned j(0); j < N; ++j)
model[i] += b(i, j) * f[j];
Mathematically the code is equivalent to:
double delta(std::inner_product(a.begin(), a.end(), model.begin(), 0.0,
std::plus<>(),
[](auto v1, auto v2)
{
return std::fabs(v1 - v2);
}));
As before delta
is a measure of the error based on the absolute value (std::inner_product
performs ordered map/reduce operation on a
and model
) . Mathematically:
Only one line of the main()
function varies:
prob.env.team.individuals = N;
to inform the search engine of the team size.
(for your ease all the code is in the examples/symbolic_regression04.cc file)