问题描述
算法简介
模拟退火算法:是基于Monte-Carlo迭代求解策略的一种随机寻优算法。
从某一较高初温出发,伴随温度参数的不断下降,结合概率突跳特性在解空间中随机寻找目标函数的全局最优解,即在局部最优解能概率性地跳出并最终趋于全局最优。
核心(概率设置机制):
模拟退火算法以一定的概率来接受一个比当前解要差的解 概率的计算:
对比:
普通贪心算法:兔子朝着比现在低的地方跳去。它找到了不远处的最低的山谷。但是这座山谷不一定最低的。
模拟退火:兔子喝醉了。它随机地跳了很长时间。这期间,它可能走向低处,也可能踏入平地。但是,它渐渐清醒了并朝最低的方向跳去。
实现思路
python实现
'''使用SA算法求解TSP问题'''
import numpy
as np
import time
import random
import matplotlib
.pyplot
as plt
T_start
= 5000.0
T_end
= 1e-8
q_ratio
= 0.98
L_max
= 1000
Num_of_city
= 31
cityList
= [(1304,2312),(3639,1315),(4177,2244),(3712,1399),
(3488,1535),(3326,1556),(3238,1229),(4196,1004),
(4312,790),(4386,570),(3007,1970),(2562,1756),
(2788,1491),(2381,1676),(1332,695),
(3715,1678),(3918,2179),(4061,2370),
(3780,2212),(3676,2578),(4029,2838),
(4263,2931),(3429,1908),(3507,2367),
(3394,2643),(3439,3201),(2935,3240),
(3140,3550),(2545,2357),(2778,2826),
(2370,2975)
]
def create_new(planing
):
'''输入当前的方案,随即交换两个位置的城市,产生一个新的临域方案'''
pos1
= random
.randint
(0,Num_of_city
-1)
pos2
= random
.randint
(0,Num_of_city
-1)
planing
[pos2
],planing
[pos1
] = planing
[pos1
],planing
[pos2
]
return planing
def distance(startplaceindex
,endplaceindex
):
'''计算两座城市之间的距离,输入为城市索引'''
x1
= cityList
[startplaceindex
][0]
y1
= cityList
[startplaceindex
][1]
x2
= cityList
[endplaceindex
][0]
y2
= cityList
[endplaceindex
][1]
return np
.sqrt
((x1
-x2
)**2+(y1
-y2
)**2)
def path_len(planing
):
'''计算当前方案下的总距离'''
path
= 0
for i
in range(Num_of_city
-1):
dis
= distance
(planing
[i
],planing
[i
+1])
path
+=dis
last_dist
= distance
(planing
[-1],planing
[0])
return path
+last_dist
if __name__
== "__main__":
np
.random
.seed
(42)
T
= T_start
best_planing
= []
count
= 0
start_time
= time
.time
()
current_planing
= [num
for num
in range(Num_of_city
)]
while(T
>=T_end
):
for i
in range(L_max
):
best_planing
= current_planing
.copy
()
current_planing
= create_new
(current_planing
)
f1
= path_len
(best_planing
)
f2
= path_len
(current_planing
)
df
= f2
- f1
if df
>= 0:
r_prod
= random
.random
()
if r_prod
>= np
.exp
(-df
/T
):
current_planing
= best_planing
.copy
()
T
*= q_ratio
count
+= 1
end_time
= time
.time
()
duration
= end_time
- start_time
print("模拟退火算法,初始温度T0={},降温系数q={},每个温度迭代{}次,共降温{}次,得到的TSP最优路径为:\n".format(T_start
,q_ratio
,L_max
,count
))
for i
in range(Num_of_city
):
print(best_planing
[i
],'-->',end
='')
print(best_planing
[0])
print("最优路径长度:",path_len
(best_planing
))
print("程序运行时间:",duration
)
best_planing
.append
(best_planing
[0])
x
= [cityList
[index
][0] for index
in best_planing
]
y
= [cityList
[index
][1] for index
in best_planing
]
plt
.figure
(figsize
=(15,10))
plt
.plot
(x
,y
,'o')
plt
.plot
(x
,y
,linewidth
=1,color
='red')
plt
.plot
(x
[0],y
[0],'v',markersize
=20)
plt
.title
('SA_TSP')
plt
.show
()
求解结果
模拟退火算法,初始温度T0=5000.0,降温系数q=0.98,每个温度迭代1000次,共降温1334次,得到的TSP最优路径为: 27 -->25 -->20 -->21 -->17 -->2 -->16 -->18 -->22 -->15 -->3 -->7 -->8 -->9 -->1 -->4 -->5 -->6 -->12 -->11 -->13 -->14 -->0 -->30 -->29 -->28 -->10 -->23 –>19 -->24 -->26 -->27 最优路径长度: 15874.315983757988 程序运行时间: 887.0035283565521
参考资料 【1】干货 | 用模拟退火(SA, Simulated Annealing)算法解决旅行商问题