1. 程式人生 > 其它 >模板:模擬退火

模板:模擬退火

技術標籤:演算法模板2021寒假

double ansx,ansy; //全域性最優解的座標
double ans=1e18,t; //全域性最優解、溫度
const double delta=0.993; //降溫係數

inline double calc_energy() { //計算整個系統的能量
	return 0;
}

void simulate_anneal() { //SA主過程
    double x=ansx,y=ansy;
    t=2000; //初始溫度
    while (t>1e-14) {
        double X=x+((rand()<<1)-RAND_MAX)
*t; double Y=y+((rand()<<1)-RAND_MAX)*t; //得出一個新的座標 double now=calc_energy(); double Delta=now-ans; if (Delta<0) { //接受 x=X,y=Y; ansx=x,ansy=y,ans=now; } else if (exp(-Delta/t)*RAND_MAX>rand()) x=X,y=Y; //以一個概率接受 t*=
delta; } } inline void Solve() { //多跑幾遍SA,減小誤差 ansx=(double)sx/n,ansy=(double)sy/n; //從平均值開始更容易接近最優解 simulate_anneal(); simulate_anneal(); simulate_anneal(); }
//#include <bits/stdc++.h>
#include <math.h>
#include <cstdio>
#include <iostream>
#include <cstring>
#define int long long using namespace std; const int mod = 1e9+7; struct node{ double x,y,z; }p[1005]; int n; double dis(double xx,double yy,double zz,int i){ double x = xx-p[i].x; double y = yy-p[i].y; double z = zz-p[i].z; return sqrt(x*x+y*y+z*z); } double sa(){ double EPS = 1e-9; double T = 100000; double delta = 0.98; double res = 1e18; double x = 0,y = 0,z = 0; while(T > EPS){ double diss = 0; int d = 0; for(int i = 0 ; i < n ; i ++){ double tmp = dis(x,y,z,i); if(tmp > diss){ diss = tmp; d = i; } } res = min(res,diss); x += (p[d].x - x)/diss*delta*T; y += (p[d].y - y)/diss*delta*T; z += (p[d].z - z)/diss*delta*T; T *= delta; } return res; } signed main(){ while(~scanf("%lld",&n) && n){ for(int i = 0 ; i < n ; i ++) scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z); printf("%.15f\n",sa()); } return 0; }