Ultra 0.9.4
Loading...
Searching...
No Matches
team.tcc
Go to the documentation of this file.
1
12
13#if !defined(ULTRA_TEAM_H)
14# error "Don't include this file directly, include the specific .h instead"
15#endif
16
17#if !defined(ULTRA_TEAM_TCC)
18#define ULTRA_TEAM_TCC
19
23template<Individual I>
24team<I>::team(std::size_t n)
25{
26 Expects(n <= max_team_size);
27
28 individuals_.resize(n);
29 signature_ = hash();
30
31 Ensures(is_valid());
32}
33
37template<Individual I>
38team<I>::team(const problem &p)
39{
40 Expects(p.params.team.individuals);
41 Expects(p.params.team.individuals <= max_team_size);
42
43 auto n(p.params.team.individuals);
44 individuals_.reserve(n);
45
46 for (std::size_t i(0); i < n; ++i)
47 individuals_.emplace_back(p);
48
49 signature_ = hash();
50
51 Ensures(is_valid());
52}
53
59template<Individual I>
60team<I>::team(std::vector<I> v) : individuals_(std::move(v))
61{
62 signature_ = hash();
63 Ensures(is_valid());
64}
65
78template<Individual I>
79unsigned team<I>::mutation(const problem &prb, double temperature)
80{
81 //const auto nm(random::element(individuals_).mutation(prb, temperature));
82 //if (nm)
83 // signature_.clear();
84 //return nm;
85
86 unsigned nm(0);
87 for (auto &i : individuals_)
88 nm += i.mutation(prb, temperature);
89
90 if (nm)
91 signature_ = hash();
92
93 return nm;
94}
95
108template<Individual I>
109team<I> crossover(const problem &prb, const team<I> &lhs, const team<I> &rhs)
110{
111 Expects(lhs.size() == rhs.size());
112
113 std::vector<I> crossed;
114 crossed.reserve(lhs.size());
115
116 std::ranges::transform(
117 lhs, rhs, std::back_inserter(crossed),
118 [&prb](const auto &i1, const auto &i2) { return crossover(prb, i1, i2); });
119
120 return team(std::move(crossed));
121}
122
136template<Individual I>
138{
140
141 for (std::size_t i(0); i < t.size(); ++i)
142 {
143 auto i_dv = extract_decision_vector(t[i]);
144
145 for (std::size_t j(0); j < i_dv.size(); ++j)
146 {
147 const auto &e(i_dv.coords[j]);
148 ret.values.push_back(i_dv.values[j]);
149 ret.coords.push_back({{i, e.coord.loc, e.coord.arg_index}, e.kind});
150 }
151 }
152
153 Ensures(ret.is_valid());
154 return ret;
155}
156
177template<Individual I>
178void team<I>::apply_decision_vector(const team_decision_vector &v)
179{
180 Expects(v.is_valid());
181
182 using ind_dv_t = ultra::decision_vector_t<I>;
183
184 std::vector<ind_dv_t> per_ind(size());
185
186 for (auto &&[value, c] : std::views::zip(v.values, v.coords))
187 {
188 Expects(c.coord.ind_index < size());
189
190 auto &ind_v(per_ind[c.coord.ind_index]);
191 ind_v.values.push_back(value);
192 ind_v.coords.push_back({{c.coord.loc, c.coord.arg_index}, c.kind});
193 }
194
195 for (std::size_t i(0); i < size(); ++i)
196 if (!per_ind[i].empty())
197 individuals_[i].apply_decision_vector(per_ind[i]);
198
199 signature_ = hash();
200 Ensures(is_valid());
201}
202
206template<Individual I>
207typename team<I>::const_iterator team<I>::begin() const noexcept
208{
209 return individuals_.begin();
210}
211
215template<Individual I>
216typename team<I>::const_iterator team<I>::end() const noexcept
217{
218 return individuals_.end();
219}
220
225template<Individual I>
226const I &team<I>::operator[](std::size_t i) const
227{
228 Expects(i < size());
229 return individuals_[i];
230}
231
235template<Individual I>
236bool team<I>::empty() const noexcept
237{
238 return individuals_.empty();
239}
240
244template<Individual I>
245std::size_t team<I>::size() const noexcept
246{
247 return individuals_.size();
248}
249
261template<Individual I> unsigned active_slots(const team<I> &t)
262{
263 return std::accumulate(t.begin(), t.end(), 0u,
264 [](unsigned n, const I &ind)
265 {
266 return n + active_slots(ind);
267 });
268}
269
284template<Individual I>
285hash_t team<I>::signature() const noexcept
286{
287 return signature_;
288}
289
294template<Individual I>
295hash_t team<I>::hash() const
296{
297 hash_t ret;
298
299 for (const auto &i : individuals_)
300 ret.combine(i.signature());
301
302 return ret;
303}
304
315template<Individual I>
316bool operator==(const team<I> &lhs, const team<I> &rhs) noexcept
317{
318 return std::ranges::equal(lhs, rhs);
319}
320
329template<Individual I>
330unsigned distance(const team<I> &lhs, const team<I> &rhs)
331{
332 Expects(lhs.size() == rhs.size());
333
334 return std::inner_product(lhs.begin(), lhs.end(), rhs.begin(), 0u,
335 std::plus{},
336 [](const auto &i1, const auto &i2)
337 {
338 return distance(i1, i2);
339 });
340}
341
345template<Individual I>
346ultra::individual::age_t team<I>::age() const
347{
348 if (empty())
349 return 0;
350
351 using age_t = ultra::individual::age_t;
352
353 const unsigned age_sum(std::accumulate(
354 begin(), end(), static_cast<age_t>(0),
355 [](age_t sum, const I &i)
356 {
357 return sum + i.age();
358 }));
359
360 return age_sum / size();
361}
362
368template<Individual I>
369void team<I>::inc_age(unsigned delta)
370{
371 for (auto &i : individuals_)
372 i.inc_age(delta);
373}
374
378template<Individual I>
379bool team<I>::is_valid() const
380{
381 if (size() > max_team_size)
382 return false;
383
384 if (std::ranges::any_of(individuals_,
385 [](const I &i) { return !i.is_valid(); }))
386 return false;
387
388 return signature_ == hash();
389}
390
399template<Individual I>
400bool team<I>::load(std::istream &in, const symbol_set &ss)
401{
402 std::size_t n;
403 if (!(in >> n) || n > max_team_size)
404 return false;
405
406 decltype(individuals_) v;
407 v.reserve(n);
408
409 for (std::size_t j(0); j < n; ++j)
410 {
411 I i;
412 if (!i.load(in, ss))
413 return false;
414
415 v.push_back(std::move(i));
416 }
417
418 individuals_ = std::move(v);
419
420 // We don't save/load signature: it can be easily calculated on the fly.
421 signature_ = hash();
422
423 return true;
424}
425
430template<Individual I>
431bool team<I>::save(std::ostream &out) const
432{
433 out << size() << '\n';
434 if (!out.good())
435 return false;
436
437 if (std::ranges::any_of(*this,
438 [&](const I &i) { return !i.save(out); }))
439 return false;
440
441 return out.good();
442}
443
451template<Individual I>
452std::ostream &operator<<(std::ostream &s, const team<I> &t)
453{
454 const auto format(out::print_format_flag(s));
455
456 for (const auto &i : t)
457 {
458 if (format == out::in_line_f)
459 s << '{';
460
461 s << i;
462
463 if (format == out::in_line_f)
464 s << '}';
465 else
466 s << '\n';
467 }
468
469 return s;
470}
471
472#endif // include guard
double distance(F f1, F f2)
Definition fitness.tcc:117
decision_vector extract_decision_vector(const individual &ind)
Definition gp/individual.cc:394
STL namespace.
std::remove_cvref_t< decltype(extract_decision_vector(std::declval< const I & >()))> decision_vector_t
Concrete decision-vector type associated with I.
Definition decision_vector.h:91
ultra::decision_vector< team_decision_coordinate > team_decision_vector
Team-specific decision-vector type used for numerical optimisation.
Definition team.h:41