Finding the minimum of x^2-9x+20 through simulated annealing:
This is a very simple example problem. Most people that are interested in simulated annealing probably could figure out the answer without even a pen and paper, so this is just to explore the method.
This process is a simulation of cooling metal to settle the structure to a stable formation. In this case we are settling a point into what is hopefully a global minimum of a polynomial.
The general idea:
Read more to see the code.
Note:
To find the minimum of another single variable function, just change the content of the function at the top, E(x).
For functions with more variables, you’ll have to add the new variables to the code as well as adjust them every iteration. For each new variable you will have to add a new line similar to “double xNew = x + ((rand()/(double)RAND_MAX)*2 – 1);” and save the new values in new variables named something like x2New.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
#include <iostream>
#include <random>
#include <time.h>
using
namespace
std;
double
E(
double
x)
{
return
x * x - 9 * x + 20;
}
int
main()
{
srand
(
time
(NULL));
const
double
e = 2.718281828;
const
double
lambda = 0.7;
double
x = (
rand
()/(
double
)RAND_MAX)*100;
cout <<
"Initial x == "
<< x << endl;
double
L = E(x);
for
(
double
T = 100; T > 0.00005; T *= lambda)
{
for
(
int
i=0;i<200; i++)
{
double
xNew = x + ((
rand
()/(
double
)RAND_MAX)*2 - 1);
double
LNew = E(xNew);
if
(LNew < L || (
rand
()/(
double
)RAND_MAX) <=
pow
(e,-(LNew-L)/T))
{
L = LNew;
x = xNew;
}
}
}
cout <<
"x == "
<< x <<
", E(x) == "
<< E(x) << endl;
return
0;
}
// Output:
//Initial x == 70.4794
//x == 4.49043, E(x) == -0.249908
|
Of course the exact solution is:
E(x) = x^2 – 9x + 20
E’(x) = 2x – 9 = 0
=> 2x = 9
=> x = 4.5
E(4.5) = (4.5)^2-9(4.5)+20
= 20.25 – 40.5 + 20
= -0.25
That program’s result is pretty close to the exact answer, not bad for a glorified guess and check.
This code is an adaption of code I found here. It solves a two variable problem, but the approach is the same.