Ultra 0.9.4
Loading...
Searching...
No Matches
search_log.tcc
Go to the documentation of this file.
1
12
13#if !defined(ULTRA_SEARCH_LOG_H)
14# error "Don't include this file directly, include the specific .h instead"
15#endif
16
17#if !defined(ULTRA_SEARCH_LOG_TCC)
18#define ULTRA_SEARCH_LOG_TCC
19
20template<Individual I, Fitness F>
21void search_log::save_dynamic(const summary<I, F> &sum,
22 const distribution<F> &fit_dist)
23{
24 if (!dynamic_file.is_open())
25 return;
26
27 if (sum.generation == 0)
28 dynamic_file << "\n\n";
29
30 dynamic_file << sum.generation;
31
32 const auto best(sum.best());
33 if (best.ind.empty())
34 dynamic_file << " ?";
35 else
36 dynamic_file << ' ' << best.fit;
37
38 const auto length_dist(sum.az.length_dist());
39 dynamic_file << ' ' << fit_dist.mean()
40 << ' ' << fit_dist.standard_deviation()
41 << ' ' << fit_dist.min()
42 << ' ' << static_cast<unsigned>(length_dist.mean())
43 << ' ' << length_dist.standard_deviation()
44 << ' ' << static_cast<unsigned>(length_dist.max());
45
46 dynamic_file << " {";
47 for (bool first(true); const auto &[k, v] : sum.az.crossover_types())
48 {
49 if (!first)
50 dynamic_file << ',';
51
52 first = false;
53 dynamic_file << k << ':' << v;
54 }
55 dynamic_file << '}';
56
57 if (best.ind.empty())
58 dynamic_file << " ?";
59 else
60 dynamic_file << " \"" << out::in_line << best.ind << '"';
61
62 dynamic_file << '\n' << std::flush;
63}
64
65template<Fitness F>
66void search_log::save_population(unsigned generation,
67 const distribution<F> &fit_dist)
68{
69 if (!population_file.is_open())
70 return;
71
72 if (generation == 0)
73 population_file << "\n\n";
74
75 population_file << generation;
76
77 for (const auto &[fit, freq] : fit_dist.seen())
78 population_file << ' ' << std::fixed << std::scientific << fit << ' '
79 << freq;
80
81 population_file << '\n' << std::flush;
82}
83
90template<Population P, Fitness F>
91void search_log::save_layers(
92 const P &pop, const summary<std::ranges::range_value_t<P>, F> &sum)
93{
94 if (!layers_file.is_open())
95 return;
96
97 const auto &params(pop.problem().params);
98
99 if (sum.generation == 0)
100 layers_file << "\n\n";
101
102 layers_file << sum.generation;
103
104 const auto layers(pop.layers());
105 for (std::size_t l(0); l < layers; ++l)
106 {
107 layers_file << ' ';
108
109 if (const auto ma(params.alps.max_age(l, layers));
110 ma == std::numeric_limits<decltype(ma)>::max())
111 layers_file << '0';
112 else
113 layers_file << ma + 1;
114
115 const auto &current_layer(pop.layer(l));
116
117 const auto &age_dist(sum.az.age_dist(current_layer));
118 const auto &fit_dist(sum.az.fit_dist(current_layer));
119
120 layers_file << ' ' << age_dist.mean()
121 << ' ' << age_dist.standard_deviation()
122 << ' ' << static_cast<unsigned>(age_dist.min())
123 << ' ' << static_cast<unsigned>(age_dist.max())
124 << ' ' << fit_dist.mean()
125 << ' ' << fit_dist.standard_deviation()
126 << ' ' << fit_dist.min()
127 << ' ' << fit_dist.max()
128 << ' ' << current_layer.size();
129 }
130
131 layers_file << '\n' << std::flush;
132}
133
153template<Population P, Fitness F>
155 const P &pop, const summary<std::ranges::range_value_t<P>, F> &sum)
156{
157 if ((!dynamic_file_path.empty() && !dynamic_file.is_open())
158 || (!layers_file_path.empty() && !layers_file.is_open())
159 || (!population_file_path.empty() && !population_file.is_open()))
160 open();
161
162 const auto fit_dist(sum.az.fit_dist());
163
164 save_dynamic(sum, fit_dist);
165 save_population(sum.generation, fit_dist);
166 save_layers(pop, sum);
167}
168
169template<Individual I, Fitness F> void search_log::save_summary(
170 const search_stats<I, F> &stats,
171 const model_measurements<F> &threshold) const
172{
173 if (!is_valid())
174 return;
175
176 tinyxml2::XMLPrinter doc;
177
178 {
179 xml_closer ultra_e(doc, "ultra");
180
181 {
182 xml_closer summary_e(doc, "summary");
183
184 set_text(doc, "runs", stats.runs());
185 set_text(doc, "elapsed_time", stats.elapsed.count());
186 set_text(doc, "success_rate", stats.success_rate(threshold));
187
188 {
189 xml_closer distributions_e(doc, "distributions");
190
191 {
192 xml_closer fitness_e(doc, "fitness");
193 set_text(doc, "mean", stats.fitness_distribution.mean());
194 set_text(doc, "standard_deviation",
195 stats.fitness_distribution.standard_deviation());
196 } // fitness
197 } // distributions
198
199 {
200 xml_closer best_e(doc, "best");
201 if (stats.best_measurements().fitness)
202 set_text(doc, "fitness", *stats.best_measurements().fitness);
203 if (stats.best_measurements().accuracy)
204 set_text(doc, "accuracy", *stats.best_measurements().accuracy);
205 set_text(doc, "run", stats.best_run());
206
207 std::ostringstream ss;
208 ss << out::in_line << stats.best_individual();
209 set_text(doc, "code", ss.str());
210 } // best
211
212 {
213 xml_closer solutions_e(doc, "solutions");
214 for (const auto good_runs(stats.good_runs(threshold));
215 const auto &gr : good_runs)
216 set_text(doc, "run", gr);
217 } // solutions
218
219 {
220 constexpr double perc(0.05);
221
222 xml_closer elite_e(doc, "elite");
223 set_attr(doc, "percentile", perc * 100.0);
224 for (const auto &e : stats.elite_runs(perc))
225 {
226 xml_closer run_summary_e(doc, "run");
227 set_attr(doc, "id", e.run);
228
229 if (e.best_measurements.fitness)
230 set_text(doc, "fitness", *e.best_measurements.fitness);
231 if (e.best_measurements.accuracy)
232 set_text(doc, "accuracy", *e.best_measurements.accuracy);
233 }
234 } // elite
235 } // summary
236
237 set_text(doc, "checksum", "00000000");
238 } // ultra
239
240 const std::string base_xml(doc.CStr());
241 const std::string signed_xml(ultra::crc32::embed_xml_signature(base_xml));
242
243 if (std::ofstream out(build_path(summary_file_path), std::ios::binary); out)
244 out.write(signed_xml.data(),
245 static_cast<std::streamsize>(signed_xml.size()));
246}
247
248#endif // include guard
T mean() const noexcept
Definition distribution.h:72
std::filesystem::path population_file_path
Definition search_log.h:65
std::filesystem::path dynamic_file_path
Definition search_log.h:51
void save_snapshot(const P &, const summary< std::ranges::range_value_t< P >, F > &)
Definition search_log.h:155
std::filesystem::path layers_file_path
Definition search_log.h:57
Definition search_stats.h:44
std::set< std::size_t > good_runs(const model_measurements< F > &) const
Definition search_stats.h:90
double success_rate(const model_measurements< F > &) const noexcept
Definition search_stats.h:170
const I & best_individual() const noexcept
Definition search_stats.h:130
distribution< F > fitness_distribution
Definition search_stats.h:71
std::chrono::milliseconds elapsed
Definition search_stats.h:76
std::size_t best_run() const noexcept
Definition search_stats.h:118
std::size_t runs() const noexcept
Definition search_stats.h:153
std::span< const run_summary > elite_runs(double=0.05) const noexcept
Definition search_stats.h:199
const model_measurements< F > & best_measurements() const noexcept
Definition search_stats.h:143
Definition evolution_summary.h:33
Definition model_measurements.h:28