骗分有风险 退火需谨慎 模拟退火学习

  先提一句,某kyh把板子改正后(忘记调参)WA95了。

  

  算法设计原型是物体的降温过程。

  温度高时,答案在乱跳,温度低时乱跳范围逐渐缩小

  一般情况下取到一个更优的解时改变其位置,否则随机决定是否改变

 

  那么算法存活的关键:随机

  为了取得更优的解,有可能放弃当前的解取到不优的位置,而是否取这个位置是由随机数决定的:

if(D<0)//如果是一个更优解
        {
           //更新答案
        }
else if(exp(-D/t)*RAND_MAX>rand())//能否接受这个差 ,注意,D在答案不优时为正
        {
            //更新答案
        }
        t*=delta;//降温 
    }
}
正确做法

  D是当前答案与最优答案的差。

  

  这是什么意思,我们姑且设rand()/RAND_MAX的期望是0.5,原式可化为

      D<T*ln2

  实际上由于rand()/RAND_MAX常常不是0.5,ln2会比较随机,但是一般在0~10内

  而..

if(tmpans<nowans){
    //更新答案
}
else if(exp(D/T)*RAND_MAX<rand()){
       // 更新答案
}
某kyh的错误做法

 

 

  变成什么了呢

    D<T*(-ln2)

  怎么可能,D可是正数。

  所以“是否取这个位置是由随机数决定的”成了一句空话

  然后他还用这个码A了(也许是题目的单峰性过于明显)

 

  注意,原码就算把这句话改掉,也不是正确的

  

double T=0.01;
while//...
{
       int tmp=now+T*(2ll*rand()-RAND_MAX);
       //...   
}    
View Code

 

    为了在求tmp时能跳到比较合理的范围,故意将t弄得很小。

  导致了什么呢

    D<T*ln2(D为正整数)

  ln2本身已经很小了,又乘上0.01

  左项正整数,而右项永远是0。

  所以还需要把T改到1e3左右的范围,因为相比较于位置的随机,权值的随机更加难以平衡。(指数)

  而位置处乘上一个小数来平衡掉

 

  ps:以上都是某kyh自己发现的,然后他改掉以后就WA95了(upd:調了下参数他又A了),他现在非常愧疚估计正在发博道歉,欢迎大家去喷他

  pps:引以为戒,独立思考,研究模板要讨论其正确性,而不是以AC为目的。

posted @ 2019-08-08 08:07  Yxsplayxs  阅读(220)  评论(1编辑  收藏  举报