60 const auto w(
static_cast<weight_t
>(wr * w_symbol::base_weight));
61 const w_symbol ws(s.get(), w);
64 if (category == undefined_category)
66 category = views_.size();
67 s->category(category);
70 for (
category_t i(views_.size()); i <= category; ++i)
71 views_.emplace_back(
"Collection " + std::to_string(i));
72 assert(category < views_.size());
74 views_[category].all.insert(ws);
77 views_[category].terminals.insert(ws);
79 views_[category].functions.insert(ws);
81 symbols_.push_back(std::move(s));
86void symbol_set::collection::sum_container::scale_weights(
double ratio, F f)
88 for (
auto &s : elems_)
92 s.weight =
static_cast<weight_t
>(s.weight * ratio);
104 Expects(views_[c].functions.size());
106 return static_cast<const function &
>(views_[c].functions.roulette());
118 return static_cast<const terminal &
>(views_[c].terminals.roulette());
148 if (random::boolean() && views_[c].functions.size())
149 return views_[c].functions.roulette();
151 return views_[c].terminals.roulette();
171 return views_[c].all.roulette();
181 for (
const auto &s : symbols_)
182 if (s->opcode() == opcode)
200 Expects(!dex.empty());
202 for (
const auto &s : symbols_)
203 if (s->name() == dex)
216 return static_cast<category_t>(views_.size());
226 return views_[c].terminals.size();
240 std::set<category_t> need;
242 for (
const auto &s : symbols_)
244 const auto arity(s->arity());
245 for (
auto i(
decltype(arity){0}); i < arity; ++i)
249 for (
const auto &i : need)
262 for (
const auto &ws : views_[s.
category()].all)
280 for (
const auto &s : ss.symbols_)
284 auto arity(s->arity());
288 for (
decltype(arity) j(0); j < arity; ++j)
290 << (j + 1 == arity ?
"" :
", ");
294 o <<
" -> " << s->category() <<
" (opcode " << s->opcode()
298 << ss.
weight(*s) <<
")\n";
311 vitaERROR <<
"Symbol set doesn't contain enough symbols";
323symbol_set::collection::collection(std::string n)
324 : all(
"all"), functions(
"functions"),
terminals(
"terminals"),
332bool symbol_set::collection::is_valid()
const
334 if (!all.is_valid() || !functions.is_valid() || !terminals.is_valid())
336 vitaERROR <<
"(inside " << name_ <<
")";
340 if (std::any_of(functions.begin(), functions.end(),
341 [](
const auto &s) { return s.sym->terminal(); }))
344 if (std::any_of(terminals.begin(), terminals.end(),
345 [](
const auto &s) { return !s.sym->terminal(); }))
348 for (
const auto &s : all)
350 if (s.sym->terminal())
352 if (std::find(terminals.begin(), terminals.end(), s) == terminals.end())
354 vitaERROR << name_ <<
": terminal " << s.sym->name()
361 if (std::find(functions.begin(), functions.end(), s) == functions.end())
363 vitaERROR << name_ <<
": function " << s.sym->name()
370 const auto ssize(all.size());
383 if (ssize < functions.size())
385 vitaERROR << name_ <<
": wrong function set size (more than symbol set)";
389 if (ssize < terminals.size())
391 vitaERROR << name_ <<
": wrong terminal set size (more than symbol set)";
395 return ssize == functions.size() + terminals.size();
408 elems_.push_back(ws);
411 std::sort(begin(), end(),
412 [](
auto s1,
auto s2) {
return s1.weight > s2.weight; });
434 const auto slot(random::sup(sum()));
437 for (
auto wedge(elems_[i].
weight);
439 wedge += elems_[++i].weight)
442 assert(i < elems_.size());
443 return *elems_[i].sym;
481 weight_t check_sum(0);
483 for (
const auto &e : elems_)
485 check_sum += e.weight;
487 if (e.weight == 0 && !e.sym->terminal())
489 vitaERROR << name_ <<
": null weight for symbol " << e.sym->name();
494 if (check_sum != sum())
496 vitaERROR << name_ <<
": incorrect cached sum of weights (stored: "
497 << sum() <<
", correct: " << check_sum <<
')';
A symbol with arity() > 0.
static const function * cast(const symbol *)
This is a short cut function.
category_t arg_category(std::size_t) const
void insert(const w_symbol &)
Inserts a weighted symbol in the container.
const symbol & roulette() const
Extracts a random symbol from the collection.
A container for the symbols used by the GP engine.
symbol * decode(opcode_t) const
symbol_set()
Sets up the object.
void clear()
Clears the current symbol set.
const function & roulette_function(category_t) const
const symbol & roulette(category_t) const
Extracts a random symbol from the symbol set without bias between terminals and functions .
bool enough_terminals() const
We want at least one terminal for every used category.
weight_t weight(const symbol &) const
symbol * insert(std::unique_ptr< symbol >, double=1.0)
Adds a new symbol to the set.
friend std::ostream & operator<<(std::ostream &, const symbol_set &)
Prints the symbol set to an output stream.
const symbol & roulette_free(category_t) const
Extracts a random symbol from the symbol set.
const terminal & roulette_terminal(category_t) const
category_t categories() const
std::size_t terminals(category_t) const
Together functions and terminals are referred to as symbols.
category_t category() const
The type (a.k.a.
A symbol with zero-arity.
virtual bool parametric() const
A parametric terminal needs an additional parameter to be evaluated.
static const terminal * cast(const symbol *)
This is a short cut function.
The main namespace for the project.
std::size_t category_t
A category provide operations which supplement or supersede those of the domain but which are restric...
unsigned opcode_t
This is the type used as key for symbol identification.