我想使用模拟退火在某个预定义的区间内找到单变量多项式函数的局部最小值。我还想尝试找到二次函数的全局最小值。
像这样的无导数算法并不是解决该问题的最佳方法,因此这仅用于研究目的。
虽然算法本身非常简单,但我不确定如何在单维或 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 范围内。
EDIT:
要在给定点附近生成位移点,您可以将其修改为
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()
对于每一个,你都会一遍又一遍地得到相同的位移)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)