模拟退火算法

模拟退火算法(智能算法)

一、算法的思想

​ 模拟退火的简单流程:在这里插入图片描述

接受概率: p t = e − ∣ f ( B ) − f ( A ) ∣ C t p_t=e^{-|{f(B)-f(A)}|C_t} pt=ef(B)f(A)Ct (metropolis准则)

1、优化问题有约束时——》建立惩罚机制(将目标函数增大或减小)
2、 C t C_t Ct的设置 :

模拟退火的概念
在这里插入图片描述

C t = 1 T t ; T t + 1 = α T t C_t=\frac{1}{T_t}; T_{t+1}= \alpha T_t Ct=Tt1;Tt+1=αTt C t C_t Ct 用温度来表示,其中 α \alpha α是常数,取0.95

两次循环,不同温度进行搜索(在同一温度下进行搜索,改变温度再进行搜索)

停止搜索的条件:(1)达到设定的迭代次数、(2)温度小于0.0000001、(3)找到最优解重复300次

3、怎么在旧解的附近找到新的解。
(1)求解函数的最优解时,新解的产生

在这里插入图片描述

​ ——code2.m

(2)旅行商问题

三种的方法:(1)交换法【随机选择两个点,进行交换】(2)移位法【随机选择3个点,将2个点之间的点移位到第三个点】(3)倒置法【随机选择两个点,将两点之间的点全部颠倒顺序】

%%  例子:TSP问题旅行商问题
Coord = [ 66.83 61.95 40    24.39 17.07 22.93 51.71 87.32 68.78 84.88 50 40 25 ;
    25.36 26.34 44.39 14.63 22.93 76.1  94.14 65.36 52.19 36.09 30 20 26] ;
%程序参数设定
t0 = 1 ; % 初 温 t0
iLk = 20 ; % 内 循 环 最 大 迭 代 次 数 iLk
oLk = 50 ; % 外 循 环 最 大 迭 代 次 数 oLk
lam = 0.95 ;   % λ lambda
istd = 0.001 ; % 若 内 循 环 函 数 值 方 差 小 于 istd 则 停 止
ostd = 0.001 ; % 若 外 循 环 函 数 值 方 差 小 于 ostd 则 停 止
ilen = 5 ;   % 内 循 环 保 存 的 目 标 函 数 值 个 数
olen = 5 ;   % 外 循 环 保 存 的 目 标 函 数 值 个 数
% 程 序 主 体
m = length( Coord ) ; % 城 市 的 个 数 m
fare = distance( Coord ) ; % 路 径 费 用 fare
path = 1 : m ; % 初 始 路 径 path
pathfar = pathfare( fare , path ) ; % 路 径 费 用 path fare
ores = zeros( 1 , olen ) ; % 外 循 环 保 存 的 目 标 函 数 值
e0 = pathfar ; % 能 量 初 值 e0
t = t0 ; % 温 度 t
for out = 1 : oLk % 外 循 环 模 拟 退 火 过 程
    ires = zeros( 1 , ilen ) ; %内循环 保 存 的 目 标 函 数 值
    for in = 1 : iLk % 内 循 环 模 拟 热 平 衡 过 程
        [ newpath , v ] = swap( path , 1 ) ; %产生新解——交换法
        e1 = pathfare( fare , newpath ) ; % 新状态能量
        % Metropolis 抽 样 稳 定 准 则
        r = min( 1 , exp( - ( e1 - e0 ) / t ) ) ;
        if rand < r
            path = newpath ; % 更 新 最 佳 状 态
            e0 = e1 ;
        end
        ires = [ ires( 2 : end ) e0 ] ; % 保 存 新 状 态 能 量
        % 内 循 环 终 止 准 则 :连 续 ilen 个 状 态 能 量 波 动 小 于 istd
        if std( ires , 1 ) < istd
            break ;
        end
    end
    ores = [ ores( 2 : end ) e0 ] ; % 保 存 新 状 态 能 量
    % 外 循 环 终 止 准 则 :连 续 olen 个 状 态 能 量 波 动 小 于 ostd
    if std( ores , 1 ) < ostd
        break ;
    end
    t = lam * t ;
end
pathfar = e0 ;
% 输 入 结 果
fprintf( '近似最优路径为:\n ' )
%disp( char( [ path , path(1) ] + 64 ) ) ;
disp(path)
fprintf( '近似最优路径路程\tpathfare=' ) ;
disp( pathfar ) ;
myplot( path , Coord , pathfar ) ;

新解的产生要旧解有关(新解的产生没有同意的定义,第一种是matlab内部函数的定义)。 ——code3.m

(3)书店买书问题

​ 找新解的方法:随机找到一本书改变买书的书店

(3)背包问题 ——code4.m

metropolis准则

​ 产生新解的方法

在这里插入图片描述

产生新解的三种情况:

价值变化 Δ f = { c ( i ) , 将 物 品 i 直 接 装 入 c ( i ) − c ( j ) , 将 物 品 i 装 入 且 物 品 j 取 出 c ( j ) − c ( i ) , 将 物 品 i 取 出 且 装 入 物 品 j \Delta f=\begin{cases} c(i),将物品i直接装入 \\ c(i)-c(j),将物品i装入且物品j取出\\ c(j)-c(i) ,将物品i取出且装入物品j\end{cases} Δf=c(i)ic(i)c(j)ijc(j)c(i)ij

模拟退火算法更倾向于解决组合优化问题

问题一

代码:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

%% 参数初始化
narvs = 2; % 变量个数
T0 = 100;   % 初始温度
T = T0; % 迭代中温度会发生改变,第一次迭代时温度就是T0
maxgen = 300;  % 最大迭代次数
Lk = 200;  % 每个温度下的迭代次数
alfa = 0.88;  % 温度衰减系数   最终
lb =[-3 4.1]; % x的下界
ub =[12.1 5.8]; % x的上界
%%  随机生成一个初始解
x0 = zeros(1,narvs);
for i = 1: narvs
    x0(i) = lb(i) + (ub(i)-lb(i))*rand(1);    
end
y0 = Obj_fun(x0); % 计算当前解的函数值

%% 定义一些保存中间过程的量,方便输出结果和画图
max_y = y0;     % 初始化找到的最佳的解对应的函数值为y0
MAXY = zeros(maxgen,1); % 记录每一次外层循环结束后找到的max_y (方便画图)

%% 模拟退火过程
for iter = 1 : maxgen  % 外循环, 我这里采用的是指定最大迭代次数
    for i = 1 : Lk  % 内循环,在每个温度下开始迭代
        y = randn(1,narvs);  % 生成1行narvs列的N(0,1)随机数
        z = y / sqrt(sum(y.^2)); % 根据新解的产生规则计算z
        x_new = x0 + z*T; % 根据新解的产生规则计算x_new的值
        % 如果这个新解的位置超出了定义域,就对其进行调整
        for j = 1: narvs
            if x_new(j) < lb(j)
                r = rand(1);
                x_new(j) = r*lb(j)+(1-r)*x0(j);
            elseif x_new(j) > ub(j)
                r = rand(1);
                x_new(j) = r*ub(j)+(1-r)*x0(j);
            end
        end
        x1 = x_new;    % 将调整后的x_new赋值给新解x1
        y1 = Obj_fun(x1);  % 计算新解的函数值
        if y1 > y0    % 如果新解函数值大于当前解的函数值
            x0 = x1; % 更新当前解为新解
            y0 = y1;
        else
            p = exp(-(y0 - y1)/T); % 根据Metropolis准则计算一个概率
            if rand(1) < p   % 生成一个随机数和这个概率比较,如果该随机数小于这个概率
                x0 = x1; % 更新当前解为新解
                y0 = y1;
            end
        end
        % 判断是否要更新找到的最佳的解
        if y0 > max_y  % 如果当前解更好,则对其进行更新
            max_y = y0;  % 更新最大的y
            best_x = x0;  % 更新找到的最好的x
        end
    end
    MAXY(iter) = max_y; % 保存本轮外循环结束后找到的最大的y
    T = alfa*T;   % 温度下降
end
disp('最佳的位置是:'); disp(best_x)
disp('此时最优值是:'); disp(max_y)
%% 画出每次迭代后找到的最大y的图形
figure
plot(1:maxgen,MAXY,'b-');
xlabel('迭代次数');
ylabel('y的值');
MATLAB是一种强大的数值计算工具,其中的模拟退火算法常用于解决优化问题,包括求解复杂函数的最小值。惩罚函数在模拟退火中扮演了关键角色,它通常是原目标函数加上一种额外的约束项或代价,目的是为了处理非凸、有局部最优的问题。 在模拟退火中,惩罚函数的设计可以有多种方式,比如: 1. **Lagrange乘子法**:如果问题存在某个约束条件,可以引入惩罚项,当违反约束时,目标函数会增加一个正比例的惩罚值,使得满足约束成为全局最优的选择。 2. **熵惩罚**:对于一些搜索空间较大而可能导致过早收敛的问题,可能会添加熵惩罚项,增加随机性的权重,防止陷入局部最优。 3. **光滑化惩罚**:对不连续或不光滑的目标函数,通过平滑替换使其变得更容易处理。 当你在MATLAB中实现模拟退火时,通常需要编写一个循环结构,每次迭代中评估当前状态的总能量(结合目标函数和惩罚函数),然后根据一定的概率接受"热"状态(即高能量状态),直到达到预设的冷却因子或最大迭代次数。下面是简化的步骤概述: ```matlab function [x, fval] = simulatedAnnealing(targetFun, initialGuess, T0, alpha, maxIter) % 初始化 x = initialGuess; T = T0; % 初始温度 fval = targetFun(x); % 初始能量 % 主循环 for iter = 1:maxIter % 生成邻居状态 neighbor = perturb(x); newFVal = targetFun(neighbor); % 计算能量差和接受概率 deltaE = newFVal - fval; if deltaE < 0 || rand() < exp(-deltaE / T) x = neighbor; fval = newFVal; end % 调整温度 T = T * alpha; end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值