模拟退火大法好
大家可能都知道随机数是个灰常神奇的东东
我们平时可能用它来搞事情(比如说编个小游戏神马的)
但是,随机数还是有大用处的,比如说就在我们接下来要讲的模拟退火算法
这个有个传送门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的
代码会在最近几日奉上