Tatooine
simulated_annealing.h
Go to the documentation of this file.
1#ifndef TATOOINE_SIMULATED_ANNEALING_H
2#define TATOOINE_SIMULATED_ANNEALING_H
3//==============================================================================
4#include <algorithm>
5#include <cmath>
6#include <iostream>
7#include <random>
8#include <utility>
9
10#include "constants.h"
11//==============================================================================
12namespace tatooine {
13//==============================================================================
14template <typename Energy, typename Status>
16 using energy_type = Energy;
17 using status_type = Status;
18 virtual auto on_new_best_status(size_t /*i*/, Energy const & /*best_energy*/,
19 Status const & /*best_status*/,
20 Energy const & /*cur_energy*/,
21 Status const & /*cur_status*/) const -> void {
22 }
23 virtual auto on_end_of_iteration(size_t /*i*/, Energy const & /*best_energy*/,
24 Status const & /*best_status*/,
25 Energy const & /*cur_energy*/,
26 Status const & /*cur_status*/) const
27 -> void {}
28 virtual auto on_using_worse(size_t /*i*/, Energy const & /*best_energy*/,
29 Status const & /*best_status*/,
30 Energy const & /*cur_energy*/,
31 Status const & /*cur_status*/) const -> void {}
32 virtual auto on_going_back(size_t /*i*/, Energy const & /*best_energy*/,
33 Status const & /*best_status*/,
34 Energy const & /*cur_energy*/,
35 Status const & /*cur_status*/) const -> void {}
36};
37//==============================================================================
38template <template <typename> typename Comparator = std::less,
39 typename InitialStatus, typename EnergyFunction,
40 typename TemperaturFunction, typename NeighborFunction,
41 typename RandomEngine>
43 InitialStatus &&initial_status, size_t const num_iterations,
44 EnergyFunction &&energy_fun, TemperaturFunction &&temperature_fun,
45 NeighborFunction &&neighbor_fun, RandomEngine &&random_engine,
47 std::decay_t<decltype(energy_fun(std::declval<InitialStatus>()))>,
48 std::decay_t<InitialStatus>> *> const &listeners = {}) {
49 using Status = std::decay_t<InitialStatus>;
50 using Energy = decltype(energy_fun(std::declval<Status>()));
51
52 Comparator<Energy> comparator;
53 std::uniform_real_distribution<double> uni01{0.0, 1.0};
54
55 Status status = std::forward<InitialStatus>(initial_status);
56 Energy energy = energy_fun(initial_status);
57
58 auto best = std::pair{energy, initial_status};
59 auto &[best_energy, best_status] = best;
60
61 for (size_t i = 0; i < num_iterations; ++i) {
62 auto t = temperature_fun(i);
63 Status new_status = neighbor_fun(status, t);
64 Energy new_energy = energy_fun(new_status);
65
66 // always accept status with better energy
67 if (comparator(new_energy, best_energy)) {
68 status = best_status = std::move(new_status);
69 energy = best_energy = std::move(new_energy);
70 for (auto const l : listeners) {
71 l->on_new_best_status(i, best_energy, best_status, energy, status);
72 }
73 for (auto const &l : listeners) {
74 l->on_end_of_iteration(i, best_energy, best_status, energy, status);
75 }
76
77 } else {
78 auto const energy_delta = new_energy - energy;
79
80 if (gcem::exp(-energy_delta / t) > uni01(random_engine)) {
81 // take new even if worse
82 status = std::move(new_status);
83 energy = std::move(new_energy);
84 for (auto const & l : listeners) {
85 l->on_using_worse(i, best_energy, best_status, energy, status);
86 }
87
88 } else {
89 // go back to best
90 status = best_status;
91 energy = best_energy;
92 for (auto const &l : listeners) {
93 l->on_going_back(i, best_energy, best_status, energy, status);
94 }
95 }
96 for (auto const &l : listeners) {
97 l->on_end_of_iteration(i, best_energy, best_status, energy, status);
98 }
99 }
100 }
101 return best;
102}
103//==============================================================================
104} // namespace tatooine
105//==============================================================================
106#endif
Definition: algorithm.h:6
auto simulated_annealing(InitialStatus &&initial_status, size_t const num_iterations, EnergyFunction &&energy_fun, TemperaturFunction &&temperature_fun, NeighborFunction &&neighbor_fun, RandomEngine &&random_engine, std::vector< simulated_annealing_listener< std::decay_t< decltype(energy_fun(std::declval< InitialStatus >()))>, std::decay_t< InitialStatus > > * > const &listeners={})
Definition: simulated_annealing.h:42
Definition: simulated_annealing.h:15
virtual auto on_using_worse(size_t, Energy const &, Status const &, Energy const &, Status const &) const -> void
Definition: simulated_annealing.h:28
Status status_type
Definition: simulated_annealing.h:17
virtual auto on_new_best_status(size_t, Energy const &, Status const &, Energy const &, Status const &) const -> void
Definition: simulated_annealing.h:18
Energy energy_type
Definition: simulated_annealing.h:16
virtual auto on_end_of_iteration(size_t, Energy const &, Status const &, Energy const &, Status const &) const -> void
Definition: simulated_annealing.h:23
virtual auto on_going_back(size_t, Energy const &, Status const &, Energy const &, Status const &) const -> void
Definition: simulated_annealing.h:32