首页 > 其他分享 >【模板】模拟退火 Simulated Annealing

【模板】模拟退火 Simulated Annealing

时间:2022-11-23 18:55:32浏览次数:63  
标签:tmp int double Simulated answ Annealing 模拟退火 ans noww

posted on 2021-05-04 18:16:24 | under 学术 | source

模拟退火适用于:

  • 你不会正解
  • 能写出估价函数,而且最优解的估价最大/小
  • 估价函数不单调,不能二分
  • 人品好

由于是个带随机数的算法,所以使用需谨慎。

首先需要这几个常量:

const double t0=/*???*/,
             delta=0.996,
             eps=1e-13,
             srd=/*???*/;

分别为:初温、降温系数、eps、随机数种子。一般来说初温越高越准确,降温系数 \(\in[0,1)\)。

接着一个随机数生成:

double rd(){return rand()*2-RAND_MAX;}

生成一个 \([-\texttt{RAND\_MAX},\texttt{RAND\_MAX}]\) 的随机数。

估价函数:

double f(...){
	...
}

要保证最优解的估价最低。

模拟退火:

void sa(){
    while(clock()<CLOCKS_PER_SEC*0.9){
        double t=t0;
        while((t*=delta)>eps){
            double tmp=ans+rd()*t;//生成随机数,可以改
            double noww=f(tmp);
            double dt=noww-answ;
            if(dt<0||exp(-dt/t)*RAND_MAX>rand()) ans=tmp,answ=noww;
        }
    }
}

注意是 \(e^{-\frac{\Delta ans}{t}}>rnd()\),其中 \(0\leq rnd()<1\)。

而且这个是求最小值的,最大值那个负号要拿掉。

主函数:

int main(){
    srand((int)srd);
	...
	ans=0;//赋初值
	answ=f(ans);
	sa();
	printf("%.3lf",ans);//输出自己改
	return 0;
}

实际例子:

#include <ctime>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
const double t0=10000,
             delta=0.996,
             eps=1e-13,
             srd=1919810;
double rd(){return rand()*2-RAND_MAX;}
struct Dot{double x,y;Dot(double a=0,double b=0):x(a),y(b){}};
Dot ans,a[1010];
double w[1010],answ;
int n;
double f(double x,double y){
    double ans=0;
    for(int i=1;i<=n;i++){
        double dx=a[i].x-x,dy=a[i].y-y;
        ans+=sqrt(dx*dx+dy*dy)*w[i];
    }
    return ans;
}
void sa(){
    while(clock()<CLOCKS_PER_SEC*0.9){
        double t=t0;
        while((t*=delta)>eps){
            Dot tmp(ans.x+rd()*t,ans.y+rd()*t);
            double noww=f(tmp.x,tmp.y);
            double dt=noww-answ;
            if(dt<0||exp(-dt/t)*RAND_MAX>rand()) ans=tmp,answ=noww;
        }
    }
}
int main(){
    srand((int)srd);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lf%lf%lf",&a[i].x,&a[i].y,&w[i]);
        ans.x+=a[i].x,ans.y+=a[i].y;
    }
    ans.x/=n,ans.y/=n,answ=f(ans.x,ans.y);
    sa();
    printf("%.3lf %.3lf",ans.x,ans.y);
    return 0;
}

标签:tmp,int,double,Simulated,answ,Annealing,模拟退火,ans,noww
From: https://www.cnblogs.com/caijianhong/p/template-Simulated-Annealing.html

相关文章

  • 模拟退火
    模拟退火(SimulateAnneal)是一种通用概率演算法,在大的搜索空间内寻找最优解,若新的状态优于当前状态,则将新的状态作为最优解,否则以一定概率接受新的状态。模拟退火有三个因......
  • 基于粒子群优化和模拟退火算法增强传统聚类研究(Matlab代码实现)
    ......
  • 模拟退火
    模拟退火很多时候我们会被要求求一些函数的最值问题,但是又因为值域很大,是连续的乃至无穷的,那么搜索是搜不出来的,对于这种问题,一般来说爬山算法是很可以的,比如下边的图......
  • 模拟退火学习笔记
    1.简介模拟退火算法来源于固体退火原理,是一种基于概率的算法,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在......
  • 模拟退火学习笔记
    虽然说考前不应该碰这些随机化算法,容易影响思考,但是还是写一写吧,对于一些问题还是很好用的。概念什么是模拟退火。一句话解释,我们从一个旧状态随机出一个新状态,要从旧状......
  • 分治理 + 模拟退火(因为博客归档有问题,这两个就放一起了,以后有机会搬一下)
    分治本篇重点讲三个东西,线段树分治,点分治,以及CDQ分治。TOP1线段树分治这个算法主要是针对于一些对在线算法很不友好的题,其模型大概是维护一张图,其中的边在某个固定......
  • 学习常用模型及算法1.模拟退火算法
    title:学习常用模型及算法1.模拟退火算法excerpt:学习数学建模常用模型及算法tags:[数学建模,matlab]categories:[学习,数学建模]index_img:https://picture-......
  • 爬山算法&&模拟退火
    constdoubledown=0.996;//降温系数constdoubleeps=1e-15;//终止温度doubleansx,ansy,answ,T;structpoint{intx,y,w;}a[Z];inlinedoubledis(doub......
  • 模拟退火(SA)算法求解容量受限的车辆路径(CVRP)问题MATLAB代码
    SA求解CVRP问题的目标函数是车辆行驶总距离最小,输入数据是solomon算例中的rc208,因为求解的是CVRP问题,所以将rc208中的后三列全部删除,剩余4列,每一列含义如下:[序号X坐标Y坐......
  • 模拟退火算法通俗讲解
    编辑:连吃十三碗校正:随心目录1. 模拟退火算法基本概念2. 模拟退火算法基本流程3. 遗传模拟退火算法matlab代码1.模拟退火算法基本概念自然凝结的、不受外界干扰而形成的......