【问题标题】:How to efficiently select neighbour in 1-dimensional and n-dimensional space for Simulated Annealing如何在 1 维和 n 维空间中有效地选择邻居进行模拟退火
【发布时间】:2015-08-27 11:34:07
【问题描述】:

我想使用模拟退火在某个预定义的区间内找到单变量多项式函数的局部最小值。我也想尝试找到二次函数的全局最小值。

像这样的无导数算法不是解决问题的最佳方法,因此仅用于学习目的。

虽然算法本身非常简单,但我不确定如何在单维或 n 维空间中有效地选择邻居。

假设我正在寻找函数的局部最小值:2*​x^​3+​x+​1 在区间 [-0.5, 30] 上,并假设区间减少到每个数字的十分之一,例如 { 1.1, 1.2 ,1.3 , ..., 29.9, 30}。

我想要实现的是随机游走和从起点到能量较低的点的收敛速度之间的平衡。

如果我每次都只是从给定的区间中选择随机数,那么就没有随机游走,算法可能会绕圈子。相反,如果通过简单地以相等的概率加上或减去 0.1 来选择下一个点,那么算法可能会变成穷举搜索 - 基于起点。

我应该如何有效地平衡单维和 n 维空间中的模拟退火邻域搜索?

【问题讨论】:

    标签: java algorithm search optimization simulated-annealing


    【解决方案1】:

    因此,您正试图找到一个“随机”靠近另一个 n 维点 P 的 n 维点 P';例如,在距离 T 处。(由于这是模拟退火,我假设您会不时减小 T)。

    这可以工作:

    double[] displacement(double t, int dimension, Random r) {
          double[] d = new double[dimension];
          for (int i=0; i<dimension; i++) d[i] = r.nextGaussian()*t;
          return d;
    }
    

    输出在所有方向上随机分布,并以原点为中心(注意r.nextDouble() 倾向于 45º 角并以 0.5 为中心)。您可以根据需要通过增加t 来改变位移; 95% 的结果将在原点的 2*t 范围内。

    编辑:

    要在给定点附近生成一个位移点,您可以将其修改为

    double[] displaced(double t, double[] p, Random r) {
          double[] d = new double[p.length];
          for (int i=0; i<p.length; i++) d[i] = p[i] + r.nextGaussian()*t;
          return d;
    }
    

    您应该为所有调用使用相同的r(因为如果您为每个调用创建一个新的Random(),您将一遍又一遍地获得相同的位移)。

    【讨论】:

    • 请澄清一下。是 t = T 吗?输出不应该以当前点为中心吗?我看不到算法如何将当前点纳入计算?或者,我应该简单地将这个位移应用到这个方法之外的当前点上,它的返回值?谢谢
    • 查看关于“起点”的编辑 (p)。是的,t 是温度; Java 中的变量通常是小写的。
    • 感谢 Random 实例的额外提示。
    • 温度和点距离应该是同一个变量吗?随着温度降低,这自然会进行更精细的搜索
    • 是的,就是这样。
    【解决方案2】:

    在“Numerical Recepies in C++”中有一章标题为“通过模拟退火进行连续最小化”。在里面我们有

    如果存在局部下坡运动时,随机变化生成器的效率很低,但它几乎总是提出上坡运动。我们认为,一个好的发电机不应该在狭窄的山谷中变得低效;随着收敛到最小值的临近,它也不应该变得越来越低效。

    然后他们继续讨论“下坡单纯形法”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多