需要求最小值的函数为:
y=sin(0.5x)+sin(2x)+cos(3x) 其中0<x<100
画出其图如下:
代码如下:
class SAA: # 模拟退火优化算法
def __init__(self,n_iter,Tmin,Xmin,Xmax): #n_iter:内部迭代次数(当温度T一定时,x随机取多少次);Tmin:温度能取得最小值;Xmin:数据可取的最小值;Xmax:数据可取的最大值
self.n_iter=n_iter
self.Tmin=Tmin
self.Xmax=Xmax
self.Xmin=Xmin
def optiumFunction(self,x): #需要优化的函数
y=np.sin(0.5*x)+np.sin(2*x)+np.cos(3*x)
return y
def main(self): #模拟退火的主体
T=1000 #T=1000 初始温度
T0=1000 #记录下初始温度 用于降火公式 T=T0/(t+1)
t=0 #用于降火公式
x=np.random.uniform(self.Xmin,self.Xmax) #随机取一个数
yBest=self.optiumFunction(x) #用于存储做好的y值
xBest=x #用于存储最好的x值
while T>=self.Tmin: # 开始进行退火
for _ in range(self.n_iter): #内部迭代 模仿粒子在高温情况下的无序状态
y=self.optiumFunction(x)
xNew=x+np.random.uniform(-0.05,0.05)*T #随机找一个新的x值
if (xNew>=self.Xmin and xNew<=self.Xmax): #xNew是否在x能取的范围内
yNew=self.optiumFunction(xNew)
if yNew<y: #当f(xNew)<f(x)时 ,以概率P=1来接受xNew为新的x值
x=xNew
else:
P=np.exp(-(yNew-y)/T) #当f(xNew)>=f(x)时 ,如果概率P=np.exp(-(yNew-y)/T)>random_P,则接受xNew为新的x值
random_P=np.random.uniform(0,1)
if P>random_P:
x=xNew
if(self.optiumFunction(x)<yBest): #判断每个值是否时最优解
yBest=self.optiumFunction(x)
xBest=x
t+=1
T=T0/(t+1) #降火公式,使T减少, 即退火
print(x,self.optiumFunction(x))
return xBest,yBest
saa=SAA(n_iter=50000,Tmin=10,Xmin=0,Xmax=100)
saa.main()
运行后结果如下:
94.82901030661766 0.4592057757219241
84.39120362424633 -2.008902109146965
41.465133715765916 2.1981790364671
47.42026228490923 -1.0604982628446262
15.38550584497801 -0.18156476246694042
46.988170722024655 -2.1840659094284347
25.442610712740212 1.3332861248600236
9.341621303277396 -2.13372682929558
33.19538927743529 -0.5963189517935298
36.79285687515275 -2.320641002392761
74.59841074247244 -2.1259312029572226
78.15399756225665 -0.11752958435890576
75.23796883227457 0.4915495398171704
61.1891398574609 -0.3746515697810637
37.23703272662969 -0.8435904402292129
96.78962652339304 -1.6607695579623227
43.81171552482401 0.6224952861453302
91.92029614242716 2.681958139820466
95.52893497893358 -0.8138694894576765
16.60709044574008 2.7778295653624947
24.171283742302407 -2.368170447827154
64.61622324506992 0.9619427799364249
61.758687805608496 -2.347070637407544
73.60017934495414 0.28643904106762086
89.139532170181 0.3383516428256651
51.21078561951579 0.450902346005402
80.50525320706731 -1.081176983572505
81.13375723540115 -0.6907468282891783
18.376440801961394 -0.42598682247826813
0.4806994470463416 1.1863783771379672
6.869783859139419 0.44500493382772666
82.57887865350696 -0.3596428914209644
30.14451430973813 -0.7520565854232092
96.41500576271419 -0.8368578029674127
7.052747838911356 -0.04858707945447982
72.08640301708132 -2.2027073393766865
19.36148057787004 0.6359550006025345
10.198824731435769 0.7563271908093377
13.4604278516987 0.5124578257039262
50.02659534263405 0.17503945927042797
98.3294719266785 1.0097974829505434
89.12903682488341 0.3372555932972756
66.64764635194504 2.355680312680832
79.28828395528603 2.5526515687088027
5.282546207545159 -1.4193200661655982
76.99068456719183 0.7363570860269021
92.83720518000655 -0.12910479374775702
99.9963395929411 -1.1740545778641789
84.70731564163952 -2.1680181950797306
55.345017862869106 -0.9957739595978223
9.617729522782868 -1.4560435835672063
7.608025558585671 -0.8154268876054742
93.57175578404188 -1.0860624534959125
46.64455844842632 -1.9222535085831567
73.68042352802448 -0.040479840432953385
21.07004403625526 -0.9298986910830154
6.372017906981423 1.0970294426292075
77.14300017768527 0.9234488747722065
88.60911966429741 0.9224106977371356
8.760715516408641 -1.5070515201015784
45.90180025363696 -0.5958000732307994
68.24594018808668 -1.425646137852072
74.24193390902721 -2.230657547638569
55.35583959016113 -1.030362150564529
53.48150623964922 0.1724472058788602
38.15388169595174 1.2196742611760143
98.0832543989975 0.531798105837958
31.291237494886133 0.7463517179473758
93.83599824464387 -0.19993640695970594
51.35013545925716 0.3486127150385774
60.955127218257516 0.5620586993350094
38.13967750174302 1.2364960412544577
29.734670813957408 1.2895347649923143
21.576012556304615 -2.036326636269971
50.67698169576526 1.2674845044243717
34.85852191791759 -1.041650285745064
70.24799031147894 -0.7357669356033054
97.68917666321117 -1.0465356389514735
8.928527160596582 -1.8887223812520213
83.27805428565371 -0.6903921658275178
67.46953280461457 1.1041402050314326
85.74995391525745 1.0013253120742909
30.277828997600146 -1.1855693451679272
50.641373919581696 1.2985453844012524
71.17436684646074 -0.6915130232240682
43.66107044377636 0.13126356786728777
48.07084397147911 1.013384171370553
71.78133242457932 -1.9300507833638092
7.405029926135451 -0.7249752569668645
52.075453333110545 0.9836228704642731
59.07467354536731 -1.6234099756911977
98.61973480045228 0.6655869309250008
69.58489502570588 0.7351445015905643
61.112065698137975 -0.03194335017484712
86.69798748170355 -1.954426410253932
75.7083086724695 1.3332251547709424
89.2833776213988 0.40954597074796417
81.54636548828822 0.7197061272847698
47.45475022489748 -0.9184022375880914
98.92076619029135 -0.5242441512561581
out[2]: (11.564013227140576, -2.3787506499240547)
通过改变内部迭代次数结果如下
当迭代50000次,即n_iter=50000时,最优解为:(11.564013227140576, -2.3787506499240547)
当迭代5000次,即n_iter=5000时,最优解为:(49.2631173890435, -2.378750649513656)
当迭代500次,即n_iter=500时,最优解为:(61.829288105789395, -2.3787503760043873)
当迭代50次,即n_iter=50时,最优解为:(49.262855528418754, -2.3787501884489357)
当迭代5次,即n_iter=5时,最优解为:(86.96090050827495, -2.3787393309246507)
发现内部迭代次数(n_iter)越大,找到的值越接近最优解.