高级搜索之模拟退火算法(Simulated Annealing,SA)

本文介绍了模拟退火算法,以爬山者在面对复杂路径选择时的热情退火过程为比喻,阐述了温度在算法中的作用,包括接受劣解概率、搜索随机性和向最优解收敛的过程。通过八皇后问题实例展示了算法的流程和性能特点。
摘要由CSDN通过智能技术生成

一、通俗理解

        依旧利用爬山的场景,作为爬山者你总是在刚开始爬山的时候热情似火,十分激进

        当位于分岔路口的时候,介于视野受限你无法知道哪条路才是通往最高峰,不同于爬山法此时你不再选择最陡峭的路,因为此时每条路对热情四溢的你来说都是一样的

        所以你先随机选择一条路,结果却发现这条路可能困难重重,无所谓,不冷静的你依然会有很大概率去走这条路

        但是,随着时间的推移,你的热情逐渐退却,体力逐渐流逝,你意识到不能再这么胡乱地选择路径了,你变得越来越冷静,思绪越来越清晰,在分岔路口你逐渐选择那些看起来更陡峭的路径,所以当你发现了随机选择的路困难重重,你只有极低概率去走

        最终,经过心路历程的变化,你终于爬到了山顶

        此时此刻,你终于恍然大悟,退火退的不是燃烧的火焰,退的是你热情的心

二、算法名称的含义

  • 温度:热情
  • 劣解:困难重重的路
  • 全局最优解:通往山顶的路
  • 局部最优解:更陡峭的路径
  • 关系
    • 温度越高,接受劣解的概率越大,搜索的随机性越强,越趋向于全局最优解
    • 温度越低,接受劣解的概率越小,搜索的随机性越弱,越趋向于局部最优解

三、基本要素

  • 状态产生函数(Generate):如何从当前状态生成新的候选状态
  • 状态评估函数(Evaluate):得到每个状态的目标函数值
  • 状态接受函数(Accept):根据温度等因素决定是否接受新生成的状态(核心)
    • 在固定温度下,接受使目标函数值下降的候选解的概率要大于接受使目标函数值上升的候选解的概率
    • 随着温度减小,接受使目标函数值上升的解的概率要逐渐减小
    • 当温度趋于0时,只接受使目标函数值下降的解
  • 降温函数(Cooling):每次迭代如何逐渐降低温度
  • 内循环终止准则:在当前温度下的搜索是否平衡
  • 外循环终止准则:整个算法何时终止

四、算法流程

  1. 初始化:
    1. 初始解:指定或随机生成
    2. 终止条件:终止温度、最大迭代次数、已经找到了最优解
  2. 迭代:
    1. 外循环终止:判断当前解是否满足终止条件,若满足则跳到4,否则继续执行
    2. 内循环终止:判断在当前温度下的搜索是否平衡,若不平衡则回到2.1,否则继续执行
    3. 产生候选解:根据当前解调用状态产生函数生成候选解
    4. 评估候选解:比较候选解和当前解的目标函数值当前解,若候选解的大则跳到2.6,否则继续执行
    5. 接受候选解:调用状态接受函数判断是否接受候选解,若不接受则回到2.2,否则继续执行
    6. 更新候选解:更新当前解为候选解
    7. 降温:调用温度更新函数降低温度,回到2.1进行新一轮迭代
  3. 输出:算法终止,输出得到的最优解

五、评测

  • 良好的收敛性:能够在有限的迭代次数内收敛到一个满意的解
  • 良好的鲁棒性:面对不同问题实例或参数设置变化时,依然可以有效地找到接近最优解的解决方案
  • 不具有完备性和最优性:模拟退火算法依旧有概率会得到局部最优解而不是全局最优解

六、八皇后问题

描述:在一个 8x8 的国际象棋棋盘上,摆放八个皇后,使得任意两个皇后都不能处于同一行、同一列或同一斜线上

import random
import math

#初始状态生成函数
def initial(size):
    state = random.sample(range(size),size)
    return state

#状态产生函数:邻域替换,即随机选取两个位置替换值
def generate(state):
    new_state = list(state)
    i, j = random.sample(range(len(state)), 2)
    new_state[i], new_state[j] = new_state[j], new_state[i]
    return new_state

#状态评估函数:冲突数越少,目标函数值越大
def evaluate(state):
    conflicts = 0
    size = len(state)
    for i in range(0,size-1):
        for j in range(i+1,size):
            diag1 = (state[i] - i) == (state[j] - j)
            diag2 = (state[i] + i) == (state[j] + j)
            if state[i] == state[j] or diag1 or diag2:
                conflicts += 1
    return conflicts

#状态接受函数
def accept(conflicts_diff,temperature):
    return random.random() < math.exp(-conflicts_diff / temperature)

#降温函数
def cooling(temperature):
    cooling_rate = 0.95
    return temperature * cooling_rate

#模拟退火算法
def simulated_annealing(state):
    temperature = 100.0
    min_temperature = 1
    interations = 0
    max_iterations = 1000

    cur_state = state
    cur_conflicts = evaluate(cur_state)

    #外循环终止准则:最低温or最大迭代次数
    while interations != max_iterations and temperature != min_temperature:
        balanced_flag = 0
        #内循环终止准则:当前温度下最大迭代次数
        while balanced_flag != 50:
            #生成候选解
            new_state = generate(cur_state)
            #评估候选解
            new_conflicts = evaluate(new_state)
            #接受候选解
            conflicts_diff = new_conflicts - cur_conflicts
            accept_flag = accept(conflicts_diff,temperature)
            if conflicts_diff < 0  or accept_flag:
                #更新候选解
                cur_state = new_state
                cur_conflicts = new_conflicts
                balanced_flag += 1
            if cur_conflicts == 0:
                return cur_state
        temperature = cooling(temperature) #降温
        interations += 1                   #迭代次数+1
    return cur_state


state = initial(8)
print('起始棋盘:', state)
result = simulated_annealing(state)
if evaluate(result) == 0:
    print('成功:', result)
else:
    print('失败:', result)

  • 26
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值