SIMLIB/C++  3.07
opt-simann.cc
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 //! \file opt-simann.cc Optimization algorithm - simulated annealing (simplified)
3 //
4 // Copyright (c) 2000-2004 Petr Peringer
5 //
6 // This library is licensed under GNU Library GPL. See the file COPYING.
7 //
8 
9 // EXPERIMENTAL
10 // simulated annealing optimization method
11 
12 #include "simlib.h"
13 #include "internal.h"
14 #include "optimize.h" // Param, ParameterVector
15 #include <cmath> // exp()
16 
17 #define debug 1 // 0=NO, 1=OPTn, >1=ALL
18 
19 namespace simlib3 {
20 
22 
23 //////////////////////////////////////////////////////////////////////////////
24 // optimization method
25 //
26 
27 ///////////////////////////////////////////////////////////////////////////////
28 // decision based on temperature
29 //
30 bool accept_bad(double eps)
31 {
32  double p = exp(6.0 * (eps - 1.0)); // go down exponentialy
33  double x = Random(); // <0,1)
34  return (x <= p);
35 }
36 
37 ///////////////////////////////////////////////////////////////////////////////
38 // next random point
39 void move_to_next_point(ParameterVector & p, double eps)
40 {
41  for (int i = 0; i < p.size(); i++) {
42  double range = p[i].Range();
43  double delta = range * (Random() - 0.5) * eps;
44  p[i] = p[i] + delta; // limited assignment
45  }
46 }
47 
48 ///////////////////////////////////////////////////////////////////////////////
49 // simulated annealing method
50 // - simplified version
51 //
52 double Optimize_simann(double (*f) (const ParameterVector & p),
53  ParameterVector & p, int MAXT)
54 {
55  int bad_count = 0;
56  double opt = 1e30;
57  double xopt = opt;
58  ParameterVector px(p);
59  //bad_count = 0; // statistic
60  for (int temp = MAXT; temp > 0; temp--) { // falling temperature
61  // random step depends on temperature
62  double eps = temp / double (MAXT);
63  ParameterVector new_p = px;
64  move_to_next_point(new_p, eps);
65  // evaluate cost function
66  double new_x = f(new_p);
67 #if debug>1 // ALL points
68  Print("%g %g %.12g\n", new_p["d"].Value(), new_p["k"].Value(), new_x);
69 #endif
70  bool bad = false;
71  if (new_x < xopt || (bad = accept_bad(eps))) { // move to next point
72  xopt = new_x; // can be worse
73  px = new_p;
74  if (bad)
75  ++bad_count;
76 #if debug==3
77  Print("# %shil step accepted: ", bad ? "up" : "down");
78  Print("%g %g %.12g\n", new_p["d"].Value(), new_p["k"].Value(),
79  new_x);
80 #endif
81  }
82  if (new_x < opt) { // accept new temporary optimum
83  opt = new_x;
84  p = new_p;
85 #if debug==1 // optima only
86  Print("%g %g %.12g\n", p["d"].Value(), p["k"].Value(), opt);
87 #endif
88  }
89  }
90 #if debug
91  Print("# %d accepted uphill steps\n", bad_count);
92 #endif
93  return opt; // return optimal value and p
94 }
95 
96 }
97 // end
double Random()
base uniform generator (range 0-0.999999...) the default implementation is simple LCG 32bit ...
Definition: random1.cc:95
double Optimize_simann(double(*f)(const ParameterVector &p), ParameterVector &p, int MAXT)
Definition: opt-simann.cc:52
bool accept_bad(double eps)
Definition: opt-simann.cc:30
int Print(const char *fmt,...)
for Output methods, can be redirected
Definition: print.cc:92
Implementation of class CalendarList interface is static - using global functions in SQS namespace...
Definition: algloop.cc:32
void move_to_next_point(ParameterVector &p, double eps)
Definition: opt-simann.cc:39
Basic optimization framework + methods.
Internal header file for SIMLIB/C++.
Main SIMLIB/C++ interface.
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34