【算法学习】模拟退火

P1337 吊打XXX

SA 无疑就这几个步骤。

  1. 设初温 t;

  2. 降低系数 down<1

  3. 设定阈值

  4. 更劣随机概率选择(温度越低,概率越低)

AI 评价:

image

#include<bits/stdc++.h>
using namespace std;
#define down 0.996 //降低系数
int n;
struct node{
int x,y,w;
}point[10006];
double ansx,ansy,answ;
double energy(double x,double y){
double r=0,dx,dy;
for(int i=1;i<=n;i++){//计算能量总和,总和越小越稳定
dx=x-point[i].x;
dy=y-point[i].y;
r+=sqrt(dx*dx+dy*dy)*point[i].w;
}
return r;
}
void sa(){
double t=3000;//设置初温,是控制接受较差解的概率
while(t>1e-15){//设置温度阈值,当温度低于阈值时,停止降温过程
double ex=ansx+(rand()*2-RAND_MAX)*t;//根据当前温度随机生成新的解
double ey=ansy+(rand()*2-RAND_MAX)*t;
double ew=energy(ex,ey);//计算新值
double de=ew-answ;//计算新值和旧值的差
if(de<0){//越小越稳定,更优
ansx=ex;
ansy=ey;
answ=ew;
}
else if(exp(-de/t)*RAND_MAX>rand()){//概率选择更劣的值,温度越小概率越小
ansx=ex;
ansy=ey;
}
t*=down;//降低温度
}
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>point[i].x>>point[i].y>>point[i].w;
ansx+=point[i].x;//初始化
ansy+=point[i].y;
}
ansx/=n;//取平均值更合理
ansy/=n;
answ=energy(ansx,ansy);//初始值
while ((double)clock()/CLOCKS_PER_SEC<0.975) sa();//卡时
printf("%.3lf %.3lf",ansx,ansy);
return 0;
}
posted @   sad_lin  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示