模式识别九--模拟退火算法的设计与实现

2024-06-12 20:38

本文主要是介绍模式识别九--模拟退火算法的设计与实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文转自:http://www.kancloud.cn/digest/prandmethod/102851

        本节的目的是记录以下学习和掌握模拟退火(Simulated Annealing,简称SA算法)过程。模拟退火算法是一种通用概率算法,用来在一个大的搜寻空间内寻找命题的最优解。这里分别使用随机模拟退火算法和确定性模拟退火算法,在MATLAB平台上进行编程,以寻找一个6-单元全连接网络的能量最小化模型。

参考书籍:Richard O. Duda, Peter E. Hart, David G. Stork 著《模式分类》

一、技术论述

1.随机方法

学习在构造模式分类器中起着中心的作用。一个通常的做法是先假设一个单参数或多参数的模型,然后根据训练样本来估计各参数的取值。当模型相当简单并且低维时,可以采用解析的方法,如求函数导数,来显式求解方程以获得最优参数。如果模型相对复杂一些,则可以通过计算局部的导数而采用梯度下降算法来解,如人工神经网络或其他一些最大似然方法。而对于更复杂的模型,经常会出现许多局部极值,上述方法的效果往往不尽人意。

如果一个问题越复杂,或者先验知识和训练样本越少,我们对能够自动搜索可行解的复杂搜索算法的依赖性就越强,如基于参数搜索的随即方法。一个通常的做法是使搜索朝着预期最优解的区域前进,同时允许一定程度的随机扰动,以发现更好的解。

2.随机搜索

这里主要研究在多个候选解中搜索最优解的方法。假设给定多个变量si,i=1,2,…,N,其中每个变量的数值都取两个离散值之一(如-1和1)。优化问题是这样描述的:确定N个si的合适取值,时下述能量函数(又称为代价函数)最小:

其中w_ij是一个实对称矩阵,取值可正可负,其中令到自身的反馈权为零(即w_ii=0),这是因为非零w_ii只是在能量函数E上增加一个与si无关的常数,不影响问题的本质。这个优化问题可以用网络和节点的方式表示,如下图所示,其中节点之间的链接对应每个权值w_ij。

3.贪心算法的局限性

如上所述,对于求解有N个变量si的能量E最小化问题,除非N的取值很小,否则往往无法直接求解,因为其构型数目高达N^2。如果使用贪心算法搜索最优的构型,需要先随机选取每个节点的起始状态,然后顺序考查每个节点从而计算与之相联系的si=1状态和si=-1状态的能量,最后选取能够降低能量的状态迁移。这种判断只用到了直接与之相连的具有非零权值的相邻节点。

这种贪心搜索算法成功找到最优解的可能性很小,因为系统常常会陷入局部能量最小值,或根本就不收敛,因此需要选择其他搜索方法。

4.模拟退火

在热力学中,固体的退火过程主要由以下三部分组成:

  1. 加温过程。其目的是增强粒子的热运动,使其偏离平衡位置。当温度足够高时,固体将熔解为液体,从而消除系统原先可能存在的非均匀态,使随后进行的冷却过程以某一平衡态为起点。熔解过程实际是系统的熵增过程,系统能量也随温度的升高而增大。
  2. 等温过程。物理学的知识告诉我们,对于与周围环境交换热量而温度不变的封闭系统,系统状态的自发变化总是朝自由能减少的方向进行,当自由能达到最小时,系统达到平衡态。
  3. 冷却过程。其目的是使粒子的热运动减弱并渐趋有序,系统能量逐渐下降,从而得到低能的晶体结构。

Metropolis等在1953年提出了重要性采样法,即以概率大小接受新状态。具体而言,在温度T时, 由当前状态i产生新状态j,两者的能量分别为Ei和Ej,若Ej小于Ei,则接受新状态j为当前状态;否则,计算概率p(∆E):

若p(∆E)大于[0,1]区间内的随机数,则仍旧接受新状态j为当前状态;若不成立则保留i为当前状态,其中k为玻尔兹曼常数,T为系统温度。上述重要性采样过程通常称为Metropolis准则:

  1. 在高温下可接受与当前状态能量差较大的新状态;
  2. 而在低温下基本只接受与当前能量差较小的新状态;
  3. 且当温度趋于零时,就不能接受比当前状态能量高的新状态。

1983年Kirkpatrick 等意识到组合优化与物理退火的相似性,并受到Metropolis 准则的启迪,提出了模拟退火算法。模拟退火算法是基于Monte Carlo 迭代求解策略的一种随机寻优算法,其出发点是基于物理退火过程与组合优化之间的相似性,模拟退火方法由某一较高初温开始,利用具有概率突跳特性的Metropolis抽样策略在解空间中进行随机搜索,伴随温度的不断下降,重复抽样过程,最终得到问题的全局最优。对比贪心算法,模拟退火算法主要的优势在于它使系统有可能从局部最小处跳出。

对于一个优化问题:

把优化问题的求解过程与统计热力学的热平衡问题进行类比,通过模拟高温物体退火过程的方法,试图找到优化问题的全局最优或近似全局最优解;

允许随着参数的调整,目标函数可以偶尔向能量增加的方向发展(对应于能量有时上升),以利于跳出局部极小的区域,随着假想温度的下降(对应于物体的退火),系统活动性降低,最终稳定在全局最小所在的区域。

5.两种模拟退火算法

两种模拟退火算法,即随机模拟退火和和确定性模拟退火算法的实现步骤如下所示:

随机模拟退火算法收敛很慢,部分原因在于其中搜索的全部的构型空间的离散本质,即构型空间是一个N维超立方体。每一次搜索轨迹都只能沿着超立方体的一条边,状态只能落在超立方体的顶点上,因此失去了完整的梯度信息。而梯度信息是可以用超立方体内部的连续状态值提供的。一种更快的方法就是以下的确定性模拟退火算法:

二、实验结果讨论

构造一个6-单元全连接网络,能量函数使用公式:

其中网络的连接权值矩阵如下:

设计步骤主要包括以下几个部分: 
编写程序[E, s_out] = RandomSimulatedAnnealing(T_max, time_max, c, s, w),实现以上算法1所述的随机模拟退火算法。这里需要设定以下参数: T_max=10,T(m+1) =c*T(m),c=0.9,进行实验,能量随温度下降次数的变化曲线如图2所示(由于模拟退火算法所得到的结果有一定的随机性,因此以下步骤均执行四次算法进行观察),四次所得到的最终构型s如图3所示。

改变参数:初始温度:T_max=5,T(m+1) =c*T(m),c=0.5,进行实验,能量随温度下降次数的变化曲线如图4所示,四次所得到的最终构型s如图5所示。

编写程序[E, s_out] = DeterministicAnnealing(T_max, time_max, c, s, w),实现以上算法2所述的确定性模拟退火算法。这里需要设定以下参数: T_max=10,T(m+1) =c*T(m),c=0.9,进行实验,能量随温度下降次数的变化曲线如图6所示,四次所得到的最终构型s如图7所示。

改变参数:初始温度:T_max=5,T(m+1) =c*T(m),c=0.5,进行实验,能量随温度下降次数的变化曲线如图8所示,四次所得到的最终构型s如图9所示。

结论:图2、3给出了多次随机模拟退火算法的运行结果,可以看到构型s不一定完全一样;能量函数E的波形在经过若干次逐渐递减的震荡后基本收敛到全局最小值-19。当改变T(1)=5,c=0.5时,从图4中可观察到能量函数E的波形极速下降,并达到较小的值,中间少了一个温度渐变和震荡调整的过程。

图6、7给出多次确定性模拟退火算法的运行结果,且每次得到的最终构型s均一致;能量函数E的波形在经过平缓递减后收敛到全局最小值-19,不出现随机模拟退火中剧烈震荡的情况。当改变T(1)=5,c=0.5时,从图8中可观察到能量函数E的波形同样呈现出极速下降的态势,并达到较小的值,中间少了一个温度渐变和调整的过程。

综合以上的实验结果,我们发现随机退火和确定性退火均能给出相似的最终解,但对于一些大规模的现实问题,随机模拟退火的运行速度很慢,而相比之下确定性退火算法要快很多,有时可以快2~3个数量级。

另外,初温T(1)和温度下降系数c的选择对算法性能也有很大影响。初温的确定应折衷考虑优化质量和优化效率,常用方法包括以下几种:

  • 均匀抽样一组状态,以各状态目标值的方差为初温;
  • 随机产生一组状态,确定两两状态间的最大目标值差|∆max|,然后依据差值,利用一定的函数确定初温。譬如T(1)=-∆/ln 
    p_r,其中p_r为初始接受概率;
  • 利用经验公式给出。

模拟退火算法设计中包括三个重要的函数:状态产生函数、状态接受函数、温度更新函数;同时在程序设计时,需遵循内循环终止准则、外循环终止准则。这些环节的设计将决定模拟退火算法的优化性能。

三、实验结果

四、简单代码实现

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 随机模拟退火函数
% 输入参数:
%   T_max:初始温度
%   time_max:最大迭代次数
%   c:温度下降比率
%   s:初始构型
%   w:权值矩阵
% 输出参数:
%   E:能量变化矩阵
%   s_out:经过算法计算后的构型
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [E, s_out] = RandomSimulatedAnnealing(T_max, time_max, c, s, w)[x, y] = size(s);time = 1;        % 迭代次数
T(time) = T_max; % 初始温度设置while (time < (time_max + 1)) % (T(time) > T_min) for i = 1:1000num = ceil(rand(1) * y); % 选择产生一个1到y之间的随机数for j = 1:ye(j) = w(num, j) * s(num) * s(j);endEa(time) = -1 / 2 * sum(e);Eb(time) = -Ea(time);if Eb(time) < Ea(time)s(num) = -s(num);elseif (exp(-(Eb(time) - Ea(time)) / T(time)) > rand())s(num) = -s(num);elses(num) = s(num);endend% 计算能量EE(time) = 0;for it = 1:6for jt = 1:6E(time) = E(time) + w(it, jt) * s(it) * s(jt);endendE(time) = E(time) * (-0.5);s_out(time,:) = s;  % 每次形成的构型time = time + 1;T(time) = T(time - 1) * c;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 确定性模拟退火函数
% 输入参数:
%   T_max:初始温度
%   time_max:最大迭代次数
%   c:温度下降比率
%   s:初始构型
%   w:权值矩阵
% 中间函数:
%   tanh(l / T):响应函数,该函数有一个隐含的重新规格化的作用
% 输出参数:
%   E:能量变化矩阵
%   s_out:经过算法计算后的构型
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [E, s_out] = DeterministicAnnealing(T_max, time_max, c, s, w)[x, y] = size(s);time = 1;        % 迭代次数
T(time) = T_max; % 初始温度设置while (time < (time_max + 1))num = ceil(rand(1) * y); % 选择产生一个1到y之间的随机数for j = 1:ye(j) = w(num, j) * s(j);endl(time) = sum(e);s(num) = tanh(l(time) / T(time));% 计算能量EE(time) = 0;for it = 1:6for jt = 1:6E(time) = E(time) + w(it, jt) * s(it) * s(jt);endendE(time) = E(time) * (-0.5);s_out(time,:) = s; % 每次形成的构型time = time + 1;T(time) = T(time - 1) * c;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%模拟退火算法实验
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear;
close all;% 网络的连接权值矩阵
w = [ 0 5 -3 4 4 1;...5 0 -1 2 -3 1;...-3 -1 0 2 2 0;...4 2 2 0 3 -3;...4 -3 2 3 0 5;...1 1 0 -3 5 0];num = 6; % 总共产生6个数 
s_in = rand(1,num); % 生成1和-1的随机序列 
s_in(s_in > 0.5) = 1; 
s_in(s_in < 0.5) = -1;
disp(['初始构型S为:',num2str(s_in)]);% 以下是随机模拟退火算法
T_max = 10;        % 初始温度设置
time_max = 100;    % 最大迭代次数
c = 0.9;           % 温度变化比率
[E1, s_out1] = RandomSimulatedAnnealing(T_max, time_max, c, s_in, w);
subplot(221),plot(E1);grid on;
title(['T(1) = ',num2str(T_max),',c = ',num2str(c),',随机模拟退火算法能量变化曲线']);
disp(['T(1) = 10,c = 0.9,随机模拟退火算法最终构型S为:',num2str(s_out1(time_max,:))]);T_max = 5;         % 初始温度设置
time_max = 100;    % 最大迭代次数
c = 0.5;           % 温度变化比率
[E2, s_out2] = RandomSimulatedAnnealing(T_max, time_max, c, s_in, w);
subplot(222),plot(E2);grid on;
title(['T(1) = ',num2str(T_max),',c = ',num2str(c),',随机模拟退火算法能量变化曲线']);
disp(['T(1) = 5,c = 0.5,随机模拟退火算法最终构型S为:',num2str(s_out2(time_max,:))]);% 以下是确定性模拟退火算法
T_max = 10;        % 初始温度设置
time_max = 100;    % 最大迭代次数
c = 0.9;           % 温度变化比率
[E3, s_out3] = DeterministicAnnealing(T_max, time_max, c, s_in, w);
subplot(223),plot(E3);grid on;
title(['T(1) = ',num2str(T_max),',c = ',num2str(c),',确定性模拟退火算法能量变化曲线']);
disp(['T(1) = 10,c = 0.9,确定性模拟退火算法最终构型S为:',num2str(s_out3(time_max,:))]);T_max = 5;         % 初始温度设置
time_max = 100;    % 最大迭代次数
c = 0.5;           % 温度变化比率
[E4, s_out4] = DeterministicAnnealing(T_max, time_max, c, s_in, w);
subplot(224),plot(E4);grid on;
title(['T(1) = ',num2str(T_max),',c = ',num2str(c),',确定性模拟退火算法能量变化曲线']);
disp(['T(1) = 5,c = 0.5,确定性模拟退火算法最终构型S为:',num2str(s_out4(time_max,:))]);

参考链接:http://www.cnblogs.com/growing/archive/2010/12/16/1908255.html

这篇关于模式识别九--模拟退火算法的设计与实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1055278

相关文章

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

Nexus安装和启动的实现教程

《Nexus安装和启动的实现教程》:本文主要介绍Nexus安装和启动的实现教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Nexus下载二、Nexus安装和启动三、关闭Nexus总结一、Nexus下载官方下载链接:DownloadWindows系统根

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

MySQL 横向衍生表(Lateral Derived Tables)的实现

《MySQL横向衍生表(LateralDerivedTables)的实现》横向衍生表适用于在需要通过子查询获取中间结果集的场景,相对于普通衍生表,横向衍生表可以引用在其之前出现过的表名,本文就来... 目录一、横向衍生表用法示例1.1 用法示例1.2 使用建议前面我们介绍过mysql中的衍生表(From子句