-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimulated_annealing.f90
54 lines (53 loc) · 2.09 KB
/
simulated_annealing.f90
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
47
48
49
50
51
52
53
54
module simulated_annealing_mod
use optim_util_mod, only: dp
implicit none
private
public :: simulated_annealing
contains
subroutine simulated_annealing(funk, x0, T0, T_min, alpha, max_iter, xmin, fmin)
! ChatGPT-4 prompt: "Implement simulated annealing."
! Simulated Annealing algorithm for unconstrained optimization
interface
function funk(x)
import :: dp
real(kind=dp), dimension(:), intent(in) :: x
real(kind=dp) :: funk
end function funk
end interface
real(kind=dp), dimension(:), intent(in) :: x0 ! Initial guess for the minimum point
real(kind=dp), intent(in) :: T0 ! Initial temperature, should be set considering the problem's scale. Reasonable default could be 1.0_dp
real(kind=dp), intent(in) :: T_min ! Minimum temperature, annealing will stop when temperature is below this. Reasonable default is 1e-3_dp
real(kind=dp), intent(in) :: alpha ! Cooling rate, a value between (0, 1), typically closer to 1, maybe 0.9_dp
integer, intent(in) :: max_iter ! Maximum number of iterations
real(kind=dp), dimension(:), intent(out) :: xmin ! Minimum point found
real(kind=dp), intent(out) :: fmin ! Function value at the minimum point
real(kind=dp), dimension(:), allocatable :: x, x_new
real(kind=dp) :: T, f, f_new, p, rand_num
integer :: i, n
n = size(x0)
allocate(x(n), x_new(n))
x = x0
f = funk(x)
T = T0
do i = 1, max_iter
call random_number(rand_num)
x_new = x + T * (2.0_dp * rand_num - 1.0_dp)
f_new = funk(x_new)
if (f_new < f) then
x = x_new
f = f_new
else
call random_number(rand_num)
p = exp((f - f_new) / T)
if (rand_num < p) then
x = x_new
f = f_new
end if
end if
T = alpha * T
if (T < T_min) exit
end do
xmin = x
fmin = funk(xmin)
end subroutine simulated_annealing
end module simulated_annealing_mod