模拟退火算法

算法概述

模拟退火算法最早在1953年被N.Metropolis等人提出,其出发点是由于物理中固体物质退火过程与一般组合优化问题具有相似性。

核心思想

  1. 初始状态:从一个初始解开始。
  2. 邻域搜索:在当前解的邻域中随机选择一个新解。
  3. 接受准则:根据当前温度和新解的质量决定是否接受新解。
  4. 降温:逐渐降低系统温度,使得接受不良解的概率减少,从而收敛到一个最优解

与其他算法的比较

爬山算法:一个人只能朝着比当下所处位置更高的位置走,逐步到达不远处的最高山峰,但是这座山峰不一定是整个空间的最高山峰,只是这个人目光所及的这一块区域的最高山峰。

模拟退火算法:一个人可以朝着比当下所处位置更高或更低的位置走,最终达到全局最高山峰。为了破除局部最优。

核心: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)


最优轨迹图为:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值