模拟退火算法是一种基于贪心算法的算法,来源于固体退火原理,当固体加热至充分高,再让其冷却的过程中,固体内部粒子再不断运动中,当冷却时候有,粒子趋于有序,当温度达到环境温度的时候,内能最低,缺点是可能会陷入局部最优解而找不到全局最优解
值得注意的是,当物体和环境温度相差大的时候,降温最为明显,当趋向于环境温度的时候,降温缓慢
每次降温为一次迭代,每次迭代会得到一个新状态,如果迭代后的新状态更优,则接受新状态,如果迭代后的新状态,则会一个概率接受该状态,这个概率随着时间推移而降低
下面给出应用场景
求y=lnx/x的极值
下面的函数图像为y=lnx/x的图像
#include <iostream>
#include <math.h>
using namespace std;
double T = 100; //起始的温度
double dT = 0.98; //降温的系数
const double eps = 1e-10; //判断是否停止
double y;
//y=lnx/x的函数
double func(double x)
{
return (1.0 * log(x) / x) ;
}
double SA()
{
double x = rand() % 100; //在0~100之间随机选择一个X值
double n = func(x); //算出当前x位置y的值
double ans = n;
while(T > eps)
{
double newx = x + (2 * rand() - RAND_MAX) * T;
// 选择[-RAND_MAX, RAND_MAX] 之间的随机数 * T 作为跳跃幅度
if(newx >= 0 && newx <= 100)
{
double next = func(newx);
ans = max(n, next);//根据情况选择最大值
//新状态更优则接受该状态
if(next - n > eps)
{
x = newx;
n = next;
}
//新状态更差,则以一个概率接受该状态接受,这个概率随这步数增加而降低
else if(exp((next - n) / T) * RAND_MAX > rand())
{
x = newx;
n = next;
}
}
T *= dT; //根据系数减少温度,模拟降温过程
}
return ans;
}
int main()
{
for(int i=0;i<100;++i)
{
printf("%.4f\n", SA());
}
return 0;
}