先给一个连接,用大白话讲的模拟退火 很容易理解
http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html
模拟退火 就是给定一个动能(或者最远能走的位置) 然后随着时间的流逝 逐渐衰减, 然后范围逐渐缩小
最后到达离最优解(当然是有误差的。。。。)
先见一个例题:
POJ 2420 http://poj.org/problem?id=2420
题意:给n个点,找出一个点,使这个点到其他所有点的距离之和最小,也就是求费马点。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 1005;
const double eps = 1e-10;
const double INF = 1e99;
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
int n;
struct point
{
double x,y;
};
point p[maxn];
double dis(point A,point B)
{
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
double calu(point a)
{
double ans=0;
for(int i=0;i<n;i++)
ans+=dis(a,p[i]);
return ans;
}
double solve()
{
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
point s=p[0],t;
double k=1,temp;
double ret=INF;
int i ,flag;
while(k>eps)
{
flag=1;
while(flag)
{
flag=0;
for(i=0;i<4;i++)
{
t.x=s.x+dx[i]*k;
t.y=s.y+dy[i]*k;
double tt=calu(t);
if(ret>tt)
{
ret=tt;
s=t;
flag=1;
}
}
}
k*=0.98;
}
return ret;
}
int main()
{
while(~scanf("%d",&n)){
double ans=solve();
printf("%.0lf\n",ans);
}
return 0;
}
下面这一题是今年 西安网络赛的一道题目
HDU 5017
http://acm.hdu.edu.cn/showproblem.php?pid=5017
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const double eps = 1e-10;
const double INF = 123456789;
int dx[8] = { 0, 0, 1, -1, 1, -1, 1, -1 };
int dy[8] = { 1, -1, 0, 0, -1, 1, 1, -1 };
double a,b,c,d,e,f;
double dis(double a,double b,double c)
{
return sqrt(a*a+b*b+c*c);
}
double calu(double x,double y)
{
double C = a*x*x+b*y*y+f*x*y-1;
double B = d*y+e*x;
double D = B*B - 4*c*C;
if(D<0) return INF;
double z1 = (-B+sqrt(D))/(2*c);
double z2 = (-B-sqrt(D))/(2*c);
return abs(z1) < abs(z2) ? z1 : z2;
}
double solve()
{
double step=1;
double x = 0,y = 0,z;
while(step>eps){
z = calu(x,y);
for(int i=0;i<8;i++){
double tmpx,tmpy,tmpz;
tmpx = x + dx[i]*step;
tmpy = y + dy[i]*step;
tmpz = calu(tmpx,tmpy);
if(tmpz == INF ) continue;
if(dis(x,y,z)>dis(tmpx,tmpy,tmpz))
x = tmpx,y=tmpy,z=tmpz;
}
step *= 0.98;
}
return dis(x,y,z);
}
int main()
{
while(~scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f)){
double ans = solve();
printf("%.5lf\n",ans);
}
return 0;
}