我想使用模拟退火在某个预定义的时间间隔内找到单变量多项式函数的局部最小值。我也想尝试找出二次函数的全局最小值。
诸如此类的无导数算法不是解决问题的最佳方法,因此仅用于研究目的。
虽然算法本身非常简单,但我不确定如何在一维或n维空间中有效选择邻居。
假设我正在寻找函数的局部最小值:在间隔[-0.5,30]上为2 * x ^ 3 + x + 1,并假设间隔减小为每个数字的十分之一,例如{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()
,您将一遍又一遍地获得相同的位移)。