Vita
i_ga.cc
Go to the documentation of this file.
1
13#include "kernel/ga/i_ga.h"
14#include "kernel/cache_hash.h"
15#include "kernel/log.h"
16#include "kernel/random.h"
17
18namespace vita
19{
29i_ga::i_ga(const problem &p) : individual(), genome_(p.sset.categories())
30{
31 Expects(parameters());
32
33 std::generate(genome_.begin(), genome_.end(),
34 [&, n = 0]() mutable
35 {
36 return static_cast<value_type>(
37 p.sset.roulette_terminal(n++).init());
38 });
39
40 Ensures(is_valid());
41}
42
51void i_ga::graphviz(std::ostream &s) const
52{
53 s << "graph {";
54
55 for (const auto &g : genome_)
56 s << "g [label=" << g << ", shape=circle];";
57
58 s << '}';
59}
60
70std::ostream &in_line(const i_ga &ga, std::ostream &s)
71{
72 std::copy(ga.begin(), ga.end(), infix_iterator<i_ga::value_type>(s, " "));
73 return s;
74}
75
85unsigned i_ga::mutation(double pgm, const problem &prb)
86{
87 Expects(0.0 <= pgm);
88 Expects(pgm <= 1.0);
89
90 unsigned n(0);
91
92 const auto ps(parameters());
93 for (category_t c(0); c < ps; ++c)
94 if (random::boolean(pgm))
95 if (const auto g =
96 static_cast<value_type>(prb.sset.roulette_terminal(c).init());
97 g != genome_[c])
98 {
99 ++n;
100 genome_[c] = g;
101 }
102
103 if (n)
104 signature_ = hash();
105
106 Ensures(is_valid());
107 return n;
108}
109
126i_ga crossover(const i_ga &lhs, const i_ga &rhs)
127{
128 Expects(lhs.parameters() == rhs.parameters());
129
130 const auto ps(lhs.parameters());
131 const auto cut1(random::sup(ps - 1));
132 const auto cut2(random::between(cut1 + 1, ps));
133
134 i_ga ret(rhs);
135 for (auto i(cut1); i < cut2; ++i)
136 ret.genome_[i] = lhs[i]; // not using `operator[](unsigned)` to avoid
137 // multiple signature resets.
138 ret.set_older_age(lhs.age());
139 ret.signature_ = ret.hash();
140
141 Ensures(ret.is_valid());
142 return ret;
143}
144
155{
156 if (signature_.empty())
157 signature_ = hash();
158
159 return signature_;
160}
161
170hash_t i_ga::hash() const
171{
172 // Length in bytes.
173 const auto len(genome_.size() * sizeof(genome_[0])); // length in bytes
174 return vita::hash::hash128(genome_.data(), len);
175}
176
184bool i_ga::operator==(const i_ga &x) const
185{
186 const bool eq(genome_ == x.genome_);
187
188 assert(signature_.empty() != x.signature_.empty() ||
189 (signature_ == x.signature_) == eq);
190
191 return eq;
192}
193
199unsigned i_ga::distance(const i_ga &ind) const
200{
201 const auto cs(parameters());
202
203 unsigned d(0);
204 for (auto i(decltype(cs){0}); i < cs; ++i)
205 if (genome_[i] != ind.genome_[i])
206 ++d;
207
208 return d;
209}
210
214bool i_ga::is_valid() const
215{
216 if (empty())
217 {
218 if (!genome_.empty())
219 {
220 vitaERROR << "Inconsistent internal status for empty individual";
221 return false;
222 }
223
224 if (!signature_.empty())
225 {
226 vitaERROR << "Empty individual must empty signature";
227 return false;
228 }
229
230 return true;
231 }
232
233 if (!signature_.empty() && signature_ != hash())
234 {
235 vitaERROR << "Wrong signature: " << signature_ << " should be " << hash();
236 return false;
237 }
238
239 return true;
240}
241
250bool i_ga::load_impl(std::istream &in, const symbol_set &)
251{
252 decltype(parameters()) sz;
253 if (!(in >> sz))
254 return false;
255
256 decltype(genome_) v(sz);
257 for (auto &g : v)
258 if (!(in >> g))
259 return false;
260
261 genome_ = v;
262
263 return true;
264}
265
270bool i_ga::save_impl(std::ostream &out) const
271{
272 out << parameters() << '\n';
273 for (const auto &g : genome_)
274 out << g << '\n';
275
276 return out.good();
277}
278
286std::ostream &operator<<(std::ostream &s, const i_ga &ind)
287{
288 return in_line(ind, s);
289}
290
297i_ga::operator std::vector<i_ga::value_type>() const
298{
299 return genome_;
300}
301
309bool operator==(const i_ga &lhs, const i_ga &rhs)
310{
311 const bool eq(std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()));
312
313 Ensures((lhs.signature() == rhs.signature()) == eq);
314 return eq;
315}
316
317} // namespace vita
An GA-individual optimized for combinatorial optimization.
Definition: i_ga.h:25
std::size_t parameters() const
Definition: i_ga.h:78
hash_t signature() const
The signature (hash value) of this individual.
Definition: i_ga.cc:154
void graphviz(std::ostream &) const
Produces a dot-language representation of this individual.
Definition: i_ga.cc:51
const_iterator begin() const
Definition: i_ga.h:118
std::ostream & in_line(const i_ga &ga, std::ostream &s)
Prints the genes of the individual.
Definition: i_ga.cc:70
const_iterator end() const
Definition: i_ga.h:126
bool is_valid() const
Definition: i_ga.cc:214
std::ostream & operator<<(std::ostream &s, const i_ga &ind)
Definition: i_ga.cc:286
bool operator==(const i_ga &) const
Definition: i_ga.cc:184
unsigned distance(const i_ga &) const
Definition: i_ga.cc:199
bool empty() const
Definition: i_ga.h:64
i_ga crossover(const i_ga &lhs, const i_ga &rhs)
Two points crossover.
Definition: i_ga.cc:126
A single member of a population.
Definition: individual.h:41
MurmurHash3 (https://github.com/aappleby/smhasher) by Austin Appleby.
Definition: cache_hash.h:101
static hash_t hash128(const void *const, std::size_t, std::uint32_t=1973)
Hashes a single message in one call, return 128-bit output.
Definition: cache_hash.h:119
Aggregates the problem-related data needed by an evolutionary program.
Definition: problem.h:24
A container for the symbols used by the GP engine.
Definition: symbol_set.h:37
const terminal & roulette_terminal(category_t) const
Definition: symbol_set.cc:113
virtual terminal_param_t init() const
Used to initialize the internal parameter of the terminal.
Definition: terminal.h:72
Contains flags and manipulators to control the output format of individuals.
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...
Definition: common.h:44
A 128bit unsigned integer used as individual's signature / hash table look-up key.
Definition: cache_hash.h:27
bool empty() const
We assume that a string of 128 zero bits means empty.
Definition: cache_hash.h:61