模拟退火算法

算法简介

模拟退火算法源于金属退火的原理。当固体温度很高时,内能较大,内部粒子进行快速的无序运动,当温度逐渐降低时,粒子运动速度逐渐下降,逐渐趋于有序,也基本趋于稳定。

在搜索全局最优解时,我们也可以先设置一个高温,然后逐渐降低温度,直到温度趋近于0。在冷却过程中,对于每个温度,都去迭代多次,来寻找局部最优解:

  • 在当前位置进行一次扰动,模拟粒子从位置 x x x跳到位置 x ′ x' x
  • 对于新的函数值,若更优,则跳到新的位置
  • 若新的位置更劣,则有概率跳到新的位置

温度趋近于0时,算法结束,即可得出最终的答案。


算法原理

为什么要有概率跳出而不是不跳出呢?因为如果现在找到了一个局部最优解,虽然它不是全局最优解,但如果在一定范围内没有比它更优的解,那最后的结果就是这个局部最优解了。如果有一定的概率能跳出,则就有可能找到另一个局部最优解。最后取所有局部最优解的最优解,得出的结果有更大概率是全局最优解。

模拟退火算法是一个近似算法,它并不能保证找到的结果是全局最优解。

其中跳出的概率 P P P满足以下公式(假设函数值最小为最优):

P = { 1 f ( x ′ ) ≤ f ( x ) e f ( x ) − f ( x ′ ) k T   f ( x ′ ) > f ( x ) P=\left\{\begin{matrix}\qquad 1 \qquad f(x')\leq f(x)\\ \\ e^{\frac{f(x)-f(x')}{kT}} \ f(x')>f(x)\end{matrix}\right. P= 1f(x)f(x)ekTf(x)f(x) f(x)>f(x)

其中 T T T表示初始温度, k k k表示温度下降的速率。

可以看出,当温度越⾼时,越有可能跳出局部最优解;当温度越⼩时,越趋向于稳定,越不容易跳出局部最优解。

在温度固定的情况下,模拟退⽕算法需要迭代多次,迭代的次数越多,越容易找到局部最优解。这个迭代次数称为⻢尔科夫链。

但⻢尔科夫链越⻓,所需要的时间也越多。


例题

【HDU - 2899】Strange fuction

题目大意:定义函数 f ( x ) = 6 x 7 + 8 x 6 + 7 x 3 + 5 x 2 + a x f(x)=6x^7+8x^6+7x^3+5x^2+ax f(x)=6x7+8x6+7x3+5x2+ax a a a已知。求当 0 ≤ x ≤ 100 0\leq x\leq 100 0x100 f ( x ) f(x) f(x)的最小值。保留四位小数。有多组数据。

模拟退火算法搜索 x x x。对于每个温度,求局部最优解。最后比较局部最优解,就能得出最后的结果。

code

#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<cstdio>
#include<cmath>
using namespace std;
int tt,T=50;
double a,t0=100,t1,t2=1e-8,k=0.98;
double f(double x){
	return 6*x*x*x*x*x*x*x+8*x*x*x*x*x*x+7*x*x*x+5*x*x-a*x; 
}
double rd(double x){
	return rand()*1.0/RAND_MAX*x;
}
int main()
{
	srand(time(NULL));
	double x,y,tx,ty,px,py;
	scanf("%d",&tt);
	while(tt--){
		scanf("%lf",&a);
		t1=t0;
		x=0;
		px=0;py=f(0);
		while(t1>t2){
			y=f(x);
			for(int i=1;i<=T;i++){
				tx=x+(rand()%2*2-1)*t1;
				if(tx<-0.01||tx>100.01) continue;
				ty=f(tx);
				if(ty<y){
					x=tx;y=ty;
				}
				else{
					if(rd(1)<exp((y-ty)/t1)){
						x=tx;y=ty;
					}
				}
				if(ty<py){
					px=tx;py=ty;
				}
			}
			t1=t1*k;
		}
		if(px<0.0) px=0.0;
		if(px>100.0) px=100.0;
		printf("%.4f\n",f(px));
	}
	return 0;
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值