MinLCA algorithms
simulated-annealing.hh
Go to the documentation of this file.
1 #ifndef __MINLCA_UTILS_SIMULATED_ANNEALING_HH
2 #define __MINLCA_UTILS_SIMULATED_ANNEALING_HH
3 
4 #include <lemon/random.h>
5 
8 
9 namespace minlca
10 {
11 namespace utils
12 {
13 
16 template<typename Node>
18 {
19 protected:
20  typedef lemon::Random Random;
21  Node *_current;
22  Node *_best;
23  int _steps;
24  int _max_steps;
25  int _stiter;
26  int _k;
27  double _lambda;
29  Random *_r;
30 
36  inline void runStep()
37  {
38  if (_current != _best and _current->energy() < 0.5 * _best->energy()) {
39  delete _current;
40  _current = _best;
41  }
42 
43  Node *next = _current->randomNeighbour();
44  double difEnergy = next->energy() - _current->energy();
45 
46 #ifdef SA_VERBOSE
47  std::string flags = "";
48 #endif
49 
50  if (_r->boolean(std::exp(difEnergy / temperature()))) {
51  if (_current != _best) {
52  delete _current;
53  }
54 
55  _current = next;
56 
57 #ifdef SA_VERBOSE
58  flags = flags + " #";
59 #endif
60 
61  if (_current->energy() > _best->energy()) {
62  delete _best;
63  _best = _current;
64 
65 #ifdef SA_VERBOSE
66  flags = flags + " *";
67 #endif
68  }
69 
70 #ifdef SA_VERBOSE
71  else {
72  flags = flags + " ++";
73  }
74 
75 #endif
76  }
77 
78 #ifdef SA_VERBOSE
79  std::cerr << "Step " << _steps << ' ' << _current->energy() << flags;
80  std::cerr << std::endl;
81 #endif
82  }
83 
84 public:
90  int steps,
91  int stIter,
92  int k,
93  double lambda,
94  int seed = 0
95  )
96  : _current(nullptr), _best(nullptr), _steps(0), _max_steps(steps),
97  _stiter(stIter), _k(k), _lambda(lambda), _delete_random(true),
98  _r(nullptr)
99  {
100  _r = new lemon::Random(seed);
101  }
102 
107  int maxSteps,
108  int stIter,
109  int k,
110  double lambda,
111  Random &r
112  )
113  : _current(nullptr), _best(nullptr), _steps(0), _max_steps(maxSteps),
114  _stiter(stIter), _k(k), _lambda(lambda), _delete_random(false), _r(&r)
115  {
116  }
117 
128  {
129  if (_current != _best and _current != nullptr) {
130  delete _current;
131  }
132 
133  if (_delete_random) {
134  delete _r;
135  }
136  }
137 
146  void init(
147  Node *start
148  )
149  {
150  _current = _best = start;
151  _steps = 0;
152  }
153 
162  virtual inline double temperature() const
163  {
164  return _k * std::exp(-_lambda * (_steps / _stiter) * _stiter);
165  }
166 
178  Node *run()
179  {
180  while (_steps < _max_steps) {
181  runStep();
182  ++_steps;
183  }
184 
185 #ifdef SA_VERBOSE
186  std::cerr << "Finished SA execution" << std::endl;
187  std::cerr << std::string(10, '-') << std::endl;
188 #endif
189 
190  if (_current != _best) {
191  delete _current;
192  _current = nullptr;
193  }
194 
195  return _best;
196  }
197 
203  Node *best()
204  {
205  return _best;
206  }
207 };
208 }
209 }
210 
211 #endif
int _max_steps
Maximum number of steps.
int _k
Coefficient for the temperature.
SimulatedAnnealing(int steps, int stIter, int k, double lambda, int seed=0)
Constructor with seed.
SimulatedAnnealing(int maxSteps, int stIter, int k, double lambda, Random &r)
Constructor using pre-built random number generator.
Generic simulated annealing algorithm.
Node * best()
Get the best node.
virtual double temperature() const
Returns the current temperature.
bool _delete_random
Delete the random number generator in destructor.
Default namespace Default namespace for MinLCA algorithms.
Definition: base.hh:15
void runStep()
Run a single step.
Node * run()
Run the algorithm.
Random * _r
Pointer to random number generator.
double _lambda
Coefficient in the exponent of the temperature.
void init(Node *start)
Initialiser for the class.