繁体   English   中英

如何在一维和n维空间中有效地选择邻域进行模拟退火

[英]How to efficiently select neighbour in 1-dimensional and n-dimensional space for Simulated Annealing

我想在一些预定义的时间间隔内使用模拟退火来找到单变量多项式函数的局部最小值。 我还想尝试找到全局最小二次函数。

诸如此类的无衍生算法不是解决该问题的最佳方法,因此这仅用于研究目的。

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

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

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

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

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

所以你试图找到一个在另一个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() ,你将一遍又一遍地获得相同的位移)。

在“C ++中的数字接收”中有一章题为“通过模拟退火的连续最小化”。 在其中我们有

如果在存在局部下坡运动时,它几乎总是提出上坡运动,则随机变化的发电机效率低。 我们认为,一个好的发电机不应该在狭窄的山谷中变得低效; 它也不会变得越来越低效,因为接近最低限度。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM