模拟退火大法好

大家可能都知道随机数是个灰常神奇的东东

我们平时可能用它来搞事情(比如说编个小游戏神马的)

但是,随机数还是有大用处的,比如说就在我们接下来要讲的模拟退火算法

这个有个传送门http://www.cnblogs.com/SXia/p/7139483.html#3733240

你们可以去看看Summer大佬对于模拟退火算法的理解

我也是看了Summer大佬的博客后才突发奇想的想写这篇文章

嗯,开始吧

这里先来做个铺垫

爬山算法

 爬山算法,顾名思义就是说,假设你在爬山,你想要去最高峰,但是你又无法知道最高峰的位置

那我们只能走我们视野中的最高的山,所以爬山算法就是去找当前位置一定区域内的最优值,而后在移过去

下面给出爬山算法的定义:爬山算法是一种简单的贪心搜索算法,该算法每次从当前解的临近解空间中选择一个最优解作为当前解,直到达到一个局部最优解。

那么我们是否能够从局部最优解推到最优解呢?

 

答案是否定的

如上图

如果我们执意要选择当前所能找到的最优点,我们只能待在原地

但是如果我们选择去往更低的山谷,我们最后就可以找到最优解哦哦哦 

这种贪心算法的漏洞非常的明显了

我们有什么办法去改正它呢?

于是我们就要用到我们之前所讲到过的随机数了

好,模拟退火算法已经呼之欲出了

模拟退火算法

模拟退火法的核心部件就是下面这段参考自http://www.cnblogs.com/CsOH/p/6049117.html的代码

1 bool accept(double delta, double temper){
2     if(delta <= 0) return true;
3     return rand() <= exp((-delta) / temper) * RAND_MAX;
4 } 

这里涉及到的有关操作,如果本人讲得不好,你们可以去看原作,我只是阐述一下我的看法

这里的temper原作表示是一个奇妙的东东,对于我来说它是一次操作所能操作的最大尺度

何为尺度,就是操作时随机数的上限,而且这个上限随着时间推移会慢慢减少,配合delta慢慢逼近答案

这里的delta是指与原来的答案的差距如果答案是减少了的,我们就可以接受这个更优解

如果答案并不比原来的解更优,我们有一定几率去接受它(就比如说我们刚刚看到的那副图)

继续使用小强大佬的计算模板

 1 double solve(){
 2     const double max_temper = 10000;
 3     double temp = max_temper;
 4     double dec = 0.999;
 5     Path p;
 6     while(temp > 0.1){
 7         Path p2(p);
 8         if(accept(p2.dist() - p.dist(), temp)) p = p2;
 9         temp *= dec;
10     }
11     return p.dist();
12 }

顺路说明一下这里Path是一种路径,负责记录到过的点

嗯嗯嗯不错不错

算是讲完了

在下给诸位来道题http://codevs.cn/problem/1344/

算是给诸位一个课后习题

其实我原来的P代码打得有点丑,最近需要去改成C的

代码会在最近几日奉上

原文地址:https://www.cnblogs.com/TUncleWangT/p/7157985.html