模拟退火实例(c++代码)

今天数学建模课讲了模拟退火~


目录

前言

待求函数 

老师的结果

我的代码 

说明

总结 


前言

模拟退火、 遗传算法这些大一时候听到的高大上的词语,终于在限选课(必须选的选修课,大一我选了,没做作业想水过去结果给挂了,大二不能申请免修淦)上学到了这两种“智能算法”。上一节课讲的遗传算法,当天就打了400+行,但是一直debug,问题不断。。。

这节课讲的模拟退火要简单许多,特此打了代码。关于模拟退火的教程,网上已经很多了,都是框架的东西,这里把实例分享给大家,结合实例学起来会好很多。


待求函数 

 

老师的结果

效果很好,but没有给出源码,自己尝试打了一下。 

我的代码 

#include<iostream>
#include<cmath>
#include<random>
#include<time.h>

using namespace std;

//---------------------------FUNCTION-------------------------//
double func(double);                            //待测函数
void LinearAnneal(double&,double);              //线性退火
void ExponentialAnneal(double&,double);         //指数退火
void ClassicalAnneal(double&,double,double);    //经典退火
void RapidAnneal(double&,double,double,double); //快速退火
void Initialize();                              //参数初始化
double EvaluationFunc(double);                  //评价函数
double Jump(double,double,double,double);

//-------------------------GlobalVariate----------------------//
double T,T0,TE;    //当前温度,初始温度,最终接受温度
double Value;      //最优状态
double ans;
double upper,lower;
int times;

int main()
{
    Initialize();
    double newans;
    while(T>TE)
    {
        newans=ans+Jump(upper,lower,T0,T);
        while(newans>upper || newans<lower)
        {
            newans=ans+Jump(upper,lower,T0,T);
        }
        if(EvaluationFunc(newans)<EvaluationFunc(ans))
        {
            ans=newans;
            if(EvaluationFunc(newans)<EvaluationFunc(Value))Value=newans;
        }
        else
        {
            double p=1-(EvaluationFunc(ans)-EvaluationFunc(newans))/T;
            if((rand()%1000)/1000.0<=p)ans=newans;
        }
        ExponentialAnneal(T,0.999);
        // LinearAnneal(T,0.1);
        // ClassicalAnneal(T,T0,times++);
        // RapidAnneal(T,T0,times++,0.98);
        cout<<"Temprature:"<<T<<","<<"\tx="<<ans<<"\ty="<<func(ans)<<"\n";
    }
    cout<<"\n=====================================\nans:"<<ans<<"\tvalue:"<<func(ans)<<"\nbest ans:"<<Value<<"\tbest value:"<<func(Value)<<"\nstandard ans:"<<1.850736<<"\tstandard value:"<<func(1.850736);
    system("pause");
    return 0;
}

double Jump(double upper,double lower,double t0,double t)
{
    double a=(rand()%(int)((upper-lower)));
    a*=pow(-1,rand()%2);
    return abs(a)>0.01?a:0.01*pow(-1,rand()%2);
}
double EvaluationFunc(double x)
{
    return -func(x);
}
void Initialize()
{
    srand(time(0));
    T=T0=1000;TE=0.1;
    Value=ans=((rand())%300)/100.0-1;
    upper=2;
    lower=-1;
    times=1;
}
double func(double x)
{
    return x*sin(10*3.1415*x)+2;
}
void LinearAnneal(double& t,double delta)       //线性退火
{
    t-=delta;
}
void ExponentialAnneal(double& t,double alpha)  //指数退火,alpha∈(0.8,0.99)
{
    t*=alpha;
}
void ClassicalAnneal(double& t,double t0,double time)    //经典退火
{
    t=t0/(log(time+1));
}
void RapidAnneal(double& t,double t0,double time,double alpha)  //快速退火
{
    t=t0/(1+alpha*time);
}

说明

说实话,这个代码的效果在我看来并不好,一些疑问请教了老师。 

总结 

这类智能算法,参数的设置都很关键,自己也是萌新,如果有大佬指教,非常高兴!! 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值