Ultra 0.9.4
Loading...
Searching...
No Matches
evolution_recombination.tcc
Go to the documentation of this file.
1
12
13#if !defined(ULTRA_EVOLUTION_RECOMBINATION_H)
14# error "Don't include this file directly, include the specific .h instead"
15#endif
16
17#if !defined(ULTRA_EVOLUTION_RECOMBINATION_TCC)
18#define ULTRA_EVOLUTION_RECOMBINATION_TCC
19
27template<Evaluator E>
28strategy<E>::strategy(E &eva, const problem &prob) : eva_(eva), prob_(prob)
29{
30}
31
38template<Evaluator E>
39template<class R>
40[[nodiscard]] auto base<E>::operator()(const R &parents) const
41 requires std::ranges::random_access_range<const R>
42 && std::ranges::sized_range<const R>
43 && std::same_as<std::ranges::range_value_t<const R>, scored_t>
44{
45 const auto &params(this->prob_.params.evolution);
46
47 Expects(in_0_1(params.p_cross));
48 Expects(params.brood_recombination);
49 Expects(std::ranges::size(parents) >= 2);
50
51 const bool use_crossover(random::boolean(params.p_cross));
52
53 const auto scored([this](auto ind)
54 {
55 auto fitness(this->eva_(ind));
56 return scored_t(std::move(ind), std::move(fitness));
57 });
58
59 const auto generate([&]
60 {
61 const auto first(std::ranges::begin(parents));
62
63 if (!use_crossover)
64 {
65 auto offspring(first[random::boolean()].ind);
66 offspring.mutation(this->prob_);
67 return scored(std::move(offspring));
68 }
69
70 auto offspring(crossover(this->prob_, first[0].ind, first[1].ind));
71
72 if (params.p_mutation > 0.0)
73 {
74 constexpr unsigned max_attempts(32);
75
76 // This could be an original contribution of Vita (now ported to Ultra) but
77 // it's hard to be sure.
78 // It remembers of the hereditary repulsion constraint (I guess you could
79 // call it signature repulsion) and seems to:
80 // - maintain diversity during the exploration phase;
81 // - optimize the exploitation phase.
82 for (unsigned i(0);
83 i < max_attempts
84 && (offspring.signature() == first[0].ind.signature()
85 || offspring.signature() == first[1].ind.signature());
86 ++i)
87 offspring.mutation(this->prob_, static_cast<double>(i + 1));
88 }
89
90 return scored(std::move(offspring));
91 });
92
93 const unsigned brood_size(use_crossover || params.p_mutation > 0.0
94 ? params.brood_recombination : 1);
95
96 auto best(generate());
97
98 for (unsigned i(1); i < brood_size; ++i)
99 if (auto candidate(generate()); candidate > best)
100 best = std::move(candidate);
101
102 return best;
103}
104
114template<Individual I>
116{
117 const auto &params(prob_.params);
118 Expects(in_0_1(params.evolution.p_cross));
119
120 return engaged.target.crossover(params.evolution.p_cross, params.de.weight,
121 engaged.base, engaged.a, engaged.b);
122}
123
124#endif // include guard
auto operator()(const R &) const
Definition evolution_recombination.h:41
I operator()(const selection::de::selected_refs< I > &) const
Definition evolution_recombination.h:116
bool boolean(double p)
Definition random.h:154
Definition evolution_selection.h:104