算法概述
模拟退火算法最早在1953年被N.Metropolis等人提出,其出发点是由于物理中固体物质退火过程与一般组合优化问题具有相似性。
核心思想:
- 初始状态:从一个初始解开始。
- 邻域搜索:在当前解的邻域中随机选择一个新解。
- 接受准则:根据当前温度和新解的质量决定是否接受新解。
- 降温:逐渐降低系统温度,使得接受不良解的概率减少,从而收敛到一个最优解
与其他算法的比较
爬山算法:一个人只能朝着比当下所处位置更高的位置走,逐步到达不远处的最高山峰,但是这座山峰不一定是整个空间的最高山峰,只是这个人目光所及的这一块区域的最高山峰。
模拟退火算法:一个人可以朝着比当下所处位置更高或更低的位置走,最终达到全局最高山峰。为了破除局部最优。
核心:SA算法的Metropolis准则允许接受一定的恶化解
算法步骤
1、初始化
选择一个处世界和初始温度
2、循环迭代
•生成一个新解(通常是通过在当前解的邻域内随机扰动生成)
•计算当前解和新解的目标函数值。
•根据Metropolis准则决定是否接受新解:
•如果新解比当前解更好,接受新解。
•如果新解更差,则以一定概率接受新解(这个概率随温度降低而降低)
•降低温度,通常采用指数衰减方式
3.终止条件
当温度降到某个阈值以下或达到预设的迭代次数时,停止算法
基于模拟退火算法TSP问题的解决(python实现)
假设十座城市坐标为(0,0), (1,5), (5,1), (2,2), (6,6), (7,3), (8,8),(7,0),(8,9),(11,2)
求解结果:
最优路径: [(2, 2), (5, 1), (7, 0), (11, 2), (7, 3), (8, 8), (8, 9), (6, 6), (1, 5), (0, 0)]
最短距离: 36.724624159273944
代码展示
import math
import random
cities = [(0,0), (1,5), (5,1), (2,2), (6,6), (7,3), (8,8),(7,0),(8,9),(11,2)]
# 计算两个城市之间的距离
def distance(city1, city2):
return math.sqrt((city1[0] - city2[0])**2 + (city1[1] - city2[1])**2)
# 计算整个路径的总距离
def total_distance(path):
dist = 0
for i in range(len(path) - 1):
dist += distance(path[i], path[i+1])
dist += distance(path[-1], path[0])
return dist
# 生成一个随机解
def random_path(cities):
path = cities[:]
random.shuffle(path)
return path
# 交换路径中的两个城市,生成新解
def swap_cities(path):
new_path = path[:]
i, j = random.sample(range(len(new_path)), 2)
new_path[i], new_path[j] = new_path[j], new_path[i]
return new_path
# 模拟退火算法
def simulated_annealing(cities):
T = 1000 # 初始温度
alpha = 0.99 # 温度衰减系数
T_end = 1e-6 # 终止温度
current_path = random_path(cities)
current_distance = total_distance(current_path)
best_path = current_path
best_distance = current_distance
while T > T_end:
new_path = swap_cities(current_path)
new_distance = total_distance(new_path)
delta = new_distance - current_distance
if delta < 0 or math.exp(-delta / T) > random.random():
current_path = new_path
current_distance = new_distance
if new_distance < best_distance:
best_path = new_path
best_distance = new_distance
T *= alpha
return best_path, best_distance
best_path, best_distance = simulated_annealing(cities)
print("最优路径:", best_path)
print("最短距离:", best_distance)
最优轨迹图为: