-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsa.py
More file actions
77 lines (54 loc) · 1.82 KB
/
sa.py
File metadata and controls
77 lines (54 loc) · 1.82 KB
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import numpy as np
import math
import random
import matplotlib.pyplot as plt
from copy import deepcopy
from tqdm import tqdm
def schaffer(x):
# x[0] in [-100, 100], x[1] in [-100, 100]
r = x[0] ** 2 + x[1] ** 2
f = 4.5 - (np.power(np.sin(np.sqrt(r)), 2) - 0.5) / np.power((1 + 0.001*r), 2)
return f
def schaffer_std(x):
return 5 - schaffer(x)
def simulated_annealing_2d(
func,
bounds = [(-100, 100), (-100, 100)],
T_init = 1000,
T_final = 1e-4,
alpha = 0.998,
step_size = 0.3,
max_iter = 1000,
):
x_c = np.array([random.uniform(bounds[0][0], bounds[0][1]), random.uniform(bounds[1][0], bounds[1][1])])
f_c = func(x_c)
x_best = deepcopy(x_c)
f_best = func(x_best)
search_history = []
t_c = T_init
while t_c > T_final:
for _ in range(max_iter):
x_new = x_c + np.random.uniform(-step_size, step_size, size=2)
x_new[0] = np.clip(x_new[0], bounds[0][0], bounds[0][1])
x_new[1] = np.clip(x_new[1], bounds[1][0], bounds[1][1])
f_new = func(x_new)
delta = f_new - f_c
if delta < 0 or random.random() < math.exp(-delta / t_c):
x_c = x_new
f_c = f_new
if f_c < f_best:
x_best = deepcopy(x_c)
f_best = f_c
search_history.append(x_best.copy())
t_c *= alpha
return x_best, f_best, search_history
if __name__ == "__main__":
np.random.seed(42)
random.seed(42)
x_result, f_result, search_history = simulated_annealing_2d(schaffer_std)
f_right = schaffer(x_result)
print(f"x = {x_result}, f = {f_right}")
x = [p[0] for p in search_history]
y = [p[1] for p in search_history]
plt.plot(x,y)
plt.show()