退火算法的java实现案例

it2025-07-23  10

一 算法背景

1. 算法解决的问题

求给定范围内函数最值问题。

2.物理背景

退火算法:退火概念来源于物理概念。当温度高时,分子能量大,使得分子空间位置处于无序状态;当温度降低,分子能量减少,分子的空间状态趋于有序(类比水的气态,液态和固态)。

此时当温度足够低时,分子排列出现一个相对最优值,这个最优值就是我们所得的最优解。

二 策略简介

特点:贪婪算法的升级版。

贪婪算法:适合求函数只有一个极值(数学概念,就是一定范围内的最小(大)值)的情况,此时极值即最值。以求函数最大值为例,当起始点是A时,它会贪婪的求出局部最大值B;当起始点是C时,它会贪婪的求出局部最大值D。但它不能求出函数最大值是D。对于简单的,只有一个极值的函数,用贪婪算法足矣。

退火算法:可以求函数的最值(数学概念,所有函数极值的最大值)。同贪婪算法,但它求出函数的极值点后,并不会停止计算,而是以一定的概率跳过该值继续计算(Metropolis接受准则),从而保证在全域(给定的)内求函数的值,从而保证求出函数的最值。

三 代码实现

本人代码实现主要参考:https://cloud.tencent.com/developer/article/1064344

1.流程图

本程序通过退火算法求出适宜的自变量的值,在通过比较各个自变量对应函数值的大小,从而得到函数的最值。

程序实现流程图如下:

2.代码使用函数

本次使用函数为:,

其中,0≤x≤100,任意输入y值,求f(z)的最值。

注:严格意义上讲,本函数在定义域内并不是多极值函数。如上图。因为怎eclipse里实现多极值函数是在太难(MATLAB就容易多了),已超出本小白的知识范围,但退火原理的基本思想仍适用。

3.代码实现

/** * 实现模拟退火算法 */ public class tuihuo { public static final int T = 100;// 初始化温度 public static final double Tmin = 1e-8;// 温度的下界 public static final int k = 100;// 迭代的次数 public static final double delta = 0.98;// 温度的下降率 //产生一个0~100之间的随机double数 public static double getX() { return Math.random() * 100; //math.random默认产生一个[0.0~1.0]之间的数。 } /**求得函数的值*/ public static double getFuncResult(double x, double y) { double result = 6 * Math.pow(x, 7) + 8 * Math.pow(x, 6) + 7 * Math.pow(x, 3) + 5 * Math.pow(x, 2) - x * y; return result; } /**模拟退火算法的过程*/ public static double getSA(double y) { //因为求函数的最小值,所以初始化为最大,同理,如果求函数最大值,初始化为最小值。 double result = Double.MAX_VALUE;// 初始化最终的结果,64位双精度值能表示的最大正数 double t = T; double x[] = new double[k]; // 初始化初始解。将数组X初始化为0~100的随机数。 for (int i = 0; i < k; i++) { x[i] = getX(); } // 迭代的过程 while (t > Tmin) { for (int i = 0; i < k; i++) { // 计算此时的函数结果 double funTmp = getFuncResult(x[i], y); // 在邻域内产生新的解 double x_new = x[i] + (Math.random() * 2 - 1) * t; // 判断新的x不能超出界 if (x_new >= 0 && x_new <= 100) { double funTmp_new = getFuncResult(x_new, y); //如果新的函数值比之前的函数值要小,则用新的x值替换原来的x值。否则, if (funTmp_new - funTmp < 0) { // 替换 x[i] = x_new; } else { // 以概率替换 double p = 1 / (1 + Math .exp(-(funTmp_new - funTmp) / T)); if (Math.random() < p) { x[i] = x_new; } } } } t = t * delta; } //结果与各个函数值作比较,得出最小值。 for (int i = 0; i < k; i++) { result = Math.min(result, getFuncResult(x[i], y)); } return result; } public static void main(String args[]) { // 设置y的值 int y = 0; System.out.println("最优解为:" + getSA(y)); } }

希望可以帮助到大家,如果不妥,可以及时联系本小白呦。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

最新回复(0)