3
0 0 1
0 2 1
1 1 1
0.577 1.000
选定一个初始状态(比如选定所有点坐标的平均数),选定一个初始温度T。
当温度大于一个边界值时:
{
随机变化坐标,变化幅度为 T 。
计算新解与当前解的差 DE。
如果新解比当前解优(DE > 0),就用新解替换当前解。
否则以 exp(DE / T) 的概率用新解替换当前解。
温度乘上一个小于1的系数,即降温。
}
这样,随着温度不断降低,变化幅度也越来越小,接受一个更劣的解的概率也越来越小。
温度T的初始值设置问题。 初始温度高,则搜索到全局最优解的可能性大,但因此要花费大量的计算时间;反之,则可节约计算时间,但全局搜索性能可能受到影响。
退火速度问题。 模拟退火算法的全局搜索性能也与退火速度密切相关。同一温度下的“充分”搜索(退火)是相当必要的,但这需要计算时间。
温度管理问题 降温系数应为正的略小于1.00的常数。
关于这道题,一切自然变化进行的方向都是使能量降低,因为能量较低的状态比较稳定。
因为物重一定,绳子越短,重物越低,势能越小,势能又与物重成正比,所以,只要使得$\sum_{i=1}^ndist[i]*weight[i]$也就是总的重力势能最小,就可以使系统平衡
#include<cmath> #include<ctime> #include<cstdio> #include<algorithm> #define pf(x) ((x)*(x)) using namespace std; const int N=1005; int n;struct node{double x,y,z;}a[N];double ansx,ansy,answ=1e9; inline double energy(double nx,double ny){ double res=0; for(int i=1;i<=n;i++) res+=sqrt(pf(nx-a[i].x)+pf(ny-a[i].y))*a[i].z; return res; } inline void SA(){ for(double T=1e5;T>=1e-14;T*=0.977){ double tx=ansx+(rand()*2-RAND_MAX)*T; double ty=ansy+(rand()*2-RAND_MAX)*T; double tw=energy(tx,ty); if(tw<answ){ ansx=tx; ansy=ty; answ=tw; } else if(exp(-(tw-answ)/T)*RAND_MAX>rand()){ ansx=tx; ansy=ty; } } } int main(){ srand(time(0)),srand(rand()+2000329); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z),ansx+=a[i].x,ansy+=a[i].y; answ=energy(ansx/=1.0*n,ansy/=1.0*n); while((clock()/(1.0*CLOCKS_PER_SEC))<=0.977) SA(); printf("%.3lf %.3lf\n",ansx,ansy); return 0; }
原文:https://www.cnblogs.com/shenben/p/11342217.html