博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模拟退火算法(一)
阅读量:6893 次
发布时间:2019-06-27

本文共 1297 字,大约阅读时间需要 4 分钟。

1、算法简介

模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。需要注意的是一定要徐徐冷却,也就是物体和外界温度相差越低,退火时间越长退火的效果就越好。这也就是这算法名字的由来。

2、基本步骤

(1)生成初始解T0

(2)生成新解Tn+1

(3)使用评价函数评价新解Tn+1,

(4)如果新解Tn+1更优秀则接受新解。

(5)否则以一定概率p接受Tn+1

(6)重复2-5步骤,直到解足够优秀。

3、关键点

算法中有4个部分是对算法质量有显著影响的。初始解,产生新解的方法,接受差解的概率p,以及评价函数。

通常要求初始解比较差,也就是被加热的温度很高。如果初始解就比较好,很容易坠入局部最优解。

产生的新解与原来的解差距比较要,也就是要徐徐的降温,降温过快就会成淬火了。

接受差解的概率p,概率不能过高也不能过低,过低会导致很容易坠入局部最优解,过高会导致收敛速度大幅下降。

通常取p=exp(-Δt′/T)。

评价函数,显而易见的评价函数能否有效表示解的优秀程度直接关系解的质量。

4、举个例子

下面以求非线性方程组的解为例,展示如何使用模拟退火算法(虽然通常解非线性方程通常不用模拟退火算法,但是用这个举例比较适合,毕竟简单)

(1)方程

funs.Add((double i,double j) =>                {                    return (Math.Sin(i) * j);                });            funs.Add((double i, double j) =>            {                return (Math.Exp(i)-j);            });

  这里我用一个List保存方程组的各个函数。这里有两个函数,分别是

f1(x,y)=ysinx=0;

f2(x,y)=e^x-y=0;

(2)产生初始解,这里为-50 ~ 50中的随机数。

double a, b;Random rd = new Random();a = rd.NextDouble()*100-50;b = rd.NextDouble()*100-50;

(3)迭代过程。

while(true){    t++;    doublet1=funs[0](a,b);    doublet2=funs[1](a,b);    //接受新解    if(Ack(t1,t2)

其中评价函数直接去了两个函数计算结果的模长。

5、总结

模拟退火算法是一种通过随机搜索寻求最优解的方法,所以其不一定能够收敛的最优解,是存在一定概率收敛在局部最优解中的。并且解的质量与计算时间有关,不过只要参数设置得当,会取得高质量解,并且速度十分迅速。

转载于:https://www.cnblogs.com/zy8095/p/3652149.html

你可能感兴趣的文章
计算机集群多任务投递脚本
查看>>
Flume数据采集之常见集群配置案例
查看>>
自定义ANDROID中EDITTEXT中的HINT文本的大小
查看>>
Unity3D下用C#通过WinSCP命令行方式给Linux服务器SCP传文件
查看>>
Fedora遇难记之rpmfusion:获取 GPG 密钥失败
查看>>
Exception
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
VC改变鼠标的WM_SETCURSOR( setcursor() )
查看>>
jQuery添加/改变/移除CSS类及判断是否已经存在CSS
查看>>
Leetcode PHP题解--D82 13. Roman to Integer
查看>>
使用scrapy抓取股票代码
查看>>
hashmap实现原理浅析
查看>>
1.1什么是数据仓库
查看>>
注册个博客好累哦
查看>>
spring mvc 如何从前台表单传递集合参数并绑定集合对象
查看>>
编程实现strcpy函数功能
查看>>
网络红人魏道道:做微商的不知道就真的“out”了
查看>>
PHP关于时间的时段的重合、 整合的方法
查看>>
awk sed grep 正则表达式
查看>>