【算法学习】模拟退火
SA 无疑就这几个步骤。
-
设初温 t;
-
降低系数 down<1
-
设定阈值
-
更劣随机概率选择(温度越低,概率越低)
AI 评价:
#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;
}