zoukankan      html  css  js  c++  java
  • 数据挖掘模拟退火算法(《集体智慧编程》第5章优化)

    一. 爬山算法 ( Hill Climbing )

             介绍模拟退火前,先介绍爬山算法。爬山算法是一种简单的贪心搜索算法,该算法每次从当前解的临近解空间中选择一个最优解作为当前解,直到达到一个局部最优解。

             爬山算法实现很简单,其主要缺点是会陷入局部最优解,而不一定能搜索到全局最优解。如图1所示:假设C点为当前解,爬山算法搜索到A点这个局部最优解就会停止搜索,因为在A点无论向那个方向小幅度移动都不能得到更优的解。

    二. 模拟退火(SA,Simulated Annealing退火)思想

             爬山法是完完全全的贪心法,每次都鼠目寸光的选择一个当前最优解,因此只能搜索到局部的最优值。模拟退火其实也是一种贪心算法,但是它的搜索过程引入了随机因素。模拟退火算法以一定的概率来接受一个比当前解要差的解,因有可能会跳出这个局部的最优解,达到全局的最优解。以图1为例,模拟退火算法在搜索到局部最优解A后,会以一定的概率接受到E的移动。也许经过几次这样的不是局部最优的移动后会到达D点,于是就跳出了局部最大值A。

             模拟退火算法描述:

             若J( Y(i+1) )>= J( Y(i) )  (即移动后得到更优解),则总是接受该移动

             若J( Y(i+1) )< J( Y(i) )  (即移动后的解比当前解要差),则以一定的概率接受移动,而且这个概率随着时间推移逐渐降低(逐渐降低才能趋向稳定)

      这里的“一定的概率”的计算参考了金属冶炼的退火过程,这也是模拟退火算法名称的由来。

      根据热力学的原理,在温度为T时,出现能量差为dE的降温的概率为P(dE),表示为:

        P(dE) = exp( dE/(kT) )

      其中k是一个常数,exp表示自然指数,且dE<0。这条公式说白了就是:温度越高,出现一次能量差为dE的降温的概率就越大;温度越低,则出现降温的概率就越小。又由于dE总是小于0(否则就不叫退火了),因此dE/kT < 0 ,所以P(dE)的函数取值范围是(0,1) 。

      随着温度T的降低,P(dE)会逐渐降低。

      我们将一次向较差解的移动看做一次温度跳变过程,我们以概率P(dE)来接受这样的移动。

      关于爬山算法与模拟退火,有一个有趣的比喻:

      爬山算法:兔子朝着比现在高的地方跳去。它找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是爬山算法,它不能保证局部最优值就是全局最优值。

      模拟退火:兔子喝醉了。它随机地跳了很长时间。这期间,它可能走向高处,也可能踏入平地。但是,它渐渐清醒了并朝最高方向跳去。这就是模拟退火。

     (

    模拟退火来自冶金学的专有名词退火退火是将材料加热后再经特定速率冷却,目的是增大晶粒的体积,并且减少晶格中的缺陷。材料中的原子原来会停留在使内能有局部最小值的位置,加热使能量变大,原子会离开原来位置,而随机在其他位置中移动。退火冷却时速度较慢,使得原子有较多可能可以找到内能比原先更低的位置。

    模拟退火的原理也和金属退火的原理近似:我们将热力学的理论套用到统计学上,将搜寻空间内每一点想像成空气内的分子;分子的能量,就是它本身的动能;而搜寻空间内的每一点,也像空气分子一样带有“能量”,以表示该点对命题的合适程度。算法先以搜寻空间内一个任意点作起始:每一步先选择一个“邻居”,然后再计算从现有位置到达“邻居”的概率。

    可以证明,模拟退火算法所得解依概率收敛到全局最优解。转自:http://zh.wikipedia.org/wiki/%E6%A8%A1%E6%8B%9F%E9%80%80%E7%81%AB

    下面给出模拟退火的伪代码表示。

     

    三. 模拟退火算法伪代码

    代码
    
    /*
    * 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 ++ ;
    }

    (一个问题:

    exp( dE/T ) > random( 0 , 1 ) 

    写错了吧,exp是递增的,dE<0,这样T越大exp(dE/T)的值越大,按你这个公式,反而时间越长越喜欢乱跳


    文章没有错,试想一下,当i越来越大时,T越来越小,为了保证dE变化的范围限制在一个很小的值,此时exp(dE/T)的值必须限制大于某个值,而不是小于某个值。

    四. 使用模拟退火算法解决旅行商问题

      旅行商问题 ( TSP , Traveling Salesman Problem ) :有N个城市,要求从其中某个问题出发,唯一遍历所有城市,再回到出发的城市,求最短的路线。

      旅行商问题属于所谓的NP完全问题,精确的解决TSP只能通过穷举所有的路径组合,其时间复杂度是O(N!) 。

      使用模拟退火算法可以比较快的求出TSP的一条近似最优路径。(使用遗传算法也是可以的,我将在下一篇文章中介绍)模拟退火解决TSP的思路:

    1. 产生一条新的遍历路径P(i+1),计算路径P(i+1)的长度L( P(i+1) )

    2. 若L(P(i+1)) < L(P(i)),则接受P(i+1)为新的路径,否则以模拟退火的那个概率接受P(i+1) ,然后降温

    3. 重复步骤1,2直到满足退出条件

      产生新的遍历路径的方法有很多,下面列举其中3种:

    1. 随机选择2个节点,交换路径中的这2个节点的顺序。

    2. 随机选择2个节点,将路径中这2个节点间的节点顺序逆转。

    3. 随机选择3个节点m,n,k,然后将节点m与n间的节点移位到节点k后面。

     

    五. 算法评价

            模拟退火算法是一种随机算法,并不一定能找到全局的最优解,可以比较快的找到问题的近似最优解。 如果参数设置得当,模拟退火算法搜索效率比穷举法要高。

    转自:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

    wikipedia上面的演算步骤:

    模拟退火算法新解的产生和接受可分为以下步骤:

    1. 由一个产生函数从当前解产生一个位于解空间的新解;为便于后续的计算和接受,减少算法耗时,通常选择由当前新解经过简单地变换即可产生新解的方法,如对构成新解的全部或部分元素进行置换、互换等,注意到产生新解的变换方法决定了当前新解的邻域结构,因而对冷却进度表的选取有一定的影响。
    2. 计算与新解所对应的目标函数差。因为目标函数差仅由变换部分产生,所以目标函数差的计算最好按增量计算。事实表明,对大多数应用而言,这是计算目标函数差的最快方法。
    3. 判断新解是否被接受,判断的依据是一个接受准则,最常用的接受准则是Metropolis准则: 若Δt′<0则接受S′作为新的当前解S,否则以概率exp(-Δt′/T)接受S′作为新的当前解S。
    4. 当新解被确定接受时,用新解代替当前解,这只需将当前解中对应于产生新解时的变换部分予以实现,同时修正目标函数值即可。此时,当前解实现了一次迭代。可在此基础上开始下一轮试验。而当新解被判定为舍弃时,则在原当前解的基础上继续下一轮试验。

    模拟退火算法与初始值无关,算法求得的解与初始解状态S(是算法迭代的起点)无关;模拟退火算法具有渐近收敛性,已在理论上被证明是一种以概率1 收敛于全局最优解的全局优化算法;模拟退火算法具有并行性。

    寻找能量E(s)最低的状态s

    s := s0; e := E(s)                           // 設定目前狀態為s0,其能量E(s0)
    k := 0                                       // 評估次數k
    while k < kmax and e > emax                  // 若還有時間(評估次數k還不到kmax)且結果還不夠好(能量e不夠低)則:
      sn := neighbour(s)                         //   隨機選取一鄰近狀態sn
      en := E(sn)                                //   sn的能量為 E(sn)
      if random() < P(e, en, temp(k/kmax)) then  //   決定是否移至鄰近狀態sn
        s := sn; e := en                         //     移至鄰近狀態sn
      k := k + 1                                 //   評估完成,次數k加一
    return s                                     // 回傳狀態s
    
    

     (

    Metropolis准则

    从物理系统倾向于能盘较低的状态,而热运动又妨碍它准确落入最低态的物理原理出发,采样时着重取那些有重要贡献的状态,则可以较快地达到较好的结果. 
    1953年,Metrop olis等提出了重要性采样法,用来产生固体的状态序列。具体做法如下:

    首先给定以粒子相对位置表征的初始状态 i 作为当前状态。然后用摄动方法使随机选取的某个粒子的位移随机地产生一微小变化,得到一个新状态 j 。

    (1)若E(j)<E(i),则状态转换被接受 
    (2)若E(j)≧E(í),则状态转换的概率为

    式中,K 是物理学中的玻耳兹曼常数,T是材料的温度.

    (3)产生随机数r=random(0,1),并与上式比较: 
    若PT ≧r, 则接受状态 j; 
    若PT < r, 则拒绝状态 j ,保持 i 不变。

    对同样的接受概率,因为T为分母,在高温下可接受的新状态能量差大一些; 而在低温下则接受的能量差较小,这与不同温度下热运动的影响一致. 当温度趋于零时,E(j ) >E(i)的新状态 j 都不能接受. 
    上述接受新状态的准则称为Metropolis准则,这种算法的计算量显著减少.

     
    《集体智慧编程》第5章主要讲的是优化问题。
     
    一个实际的例子是组团旅游。
     
  • 相关阅读:
    python中 __new__和__init__
    生成器
    边缘与轮廓
    霍夫变换
    高级滤波
    基本形态学滤波
    基本图形的绘制(基于skimage)
    图像的自动阈值分割
    图像的简单滤波
    直方图与均衡化
  • 原文地址:https://www.cnblogs.com/youxin/p/3419718.html
Copyright © 2011-2022 走看看