模拟退火
模拟降温的过程:温度越高时温度下降越多,温度越低(稳定)时,温度下降越少
首先由爬山算法开始
爬山算法:即完完全全的贪心算法,只找到眼前的山峰最高值。
但从c点开始时,我们发现找到的A点不是全局最优解,这也是贪心的缺点。
模拟退火是在爬山算法上做的改进:
其核心是:即使找到的不是最优解,也有概率选择它
这样就能跳出贪心的局部最优,搜索到全局最优
概率符合退火规律:范围越不确定时,跳出概率越大;随着范围缩小,跳出概率越低
很合理了。
上图山坡的例子,当找到A点后,再找E点,有概率选择到E点。
以下是网上他人的伪代码,我认为很好理解: http://www.cnblogs.com/heaad/
/*
* J(y):在状态y时的评价函数值
* Y(i):表示当前状态
* Y(i+1):表示新的状态
* r: 用于控制降温的快慢
* T: 系统的温度,系统初始应该要处于一个高温的状态
* T_min :温度的下限,若温度T达到T_min,则停止搜索
*/
while( T > T_min )
{
dE = J( Y(i+1) ) - J( Y(i) ) ;
if ( dE >=0 ) //表达移动后得到更优解,则总是接受移动
Y(i+1) = Y(i) ; //接受从Y(i)到Y(i+1)的移动
else
{
// 函数exp( dE/T )的取值范围是(0,1) ,dE/T越大,则exp( dE/T )也
if ( exp( dE/T ) > random( 0 , 1 ) )
Y(i+1) = Y(i) ; //接受从Y(i)到Y(i+1)的移动
}
T = r * T ; //降温退火 ,0<r<1 。r越大,降温越慢;r越小,降温越快
/*
* 若r过大,则搜索到全局最优解的可能会较高,但搜索的过程也就较长。若r过小,则搜索的过程会很快,但最终可能会达到一个局部最优值
*/
i ++ ;
}
关于火候的把握
理解了上述退火的思想,我们也应该发现:
找到全局最优解只是个概率事件!!!
而决定概率的一共有三个变量:
- 温度的初始值
- 退火速度
- 模拟次数(温度管理)
聪明的你也应该会发现:
- 如果退火速度太慢\次数太高\范围太大 会导致tle
- 如果退火速度太快\次数太低\范围太小 会导致wa
- 使用的rand函数若取的运气不好,会出现一样的代码一次wa,一次ac的神奇现象
一般的做题步骤:
求到n个点最短距离的点坐标
随机生成几个点(看题目给的点个数差不多一样就行)rand函数;
对每个点模拟30~50次不等rand函数(具体模拟就是从该点走随机个步数到一个新点,比较一下最近的距离是不是最优,若是,更新)
输出最后更新的那个点就是解。
退火思想:每个点模拟时,范围越大,rand函数走出的步长越长,范围越小时,rand越小,结果越接近。找一个起始点(零点吧);在给定点中找出最近的点和其距离;更新起始点,向最近点靠近
s.x+=(P[k].x-s.x)/d*T;
s.y+=(P[k].y-s.y)/d*T;
退火思想:范围越大靠近的距离越多,范围越小时,靠近的距离越小