码迷,mamicode.com
首页 > 编程语言 > 详细

爬山算法 模拟退火

时间:2015-09-03 17:58:01      阅读:275      评论:0      收藏:0      [点我收藏+]

标签:

bzoj3680 吊打XXX

题目大意:给定一些绳子和绳子上的重量,求出最后绳结的坐标。

思路:这个位置就是广义费马点,就是所有点到这个点的距离*每个点的权值最小的点。模拟退火,各种调常数。

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#define maxnode 10005
using namespace std;
struct use{
    double x,y,gi;
}ai[maxnode]={0},ans;
double minn=999999999999999LL;
int n;
double ran(){return rand()%1000/1000.0;}
double fang(double a){return a*a;}
double dis(use a,use b){return sqrt(fang(a.x-b.x)+fang(a.y-b.y));}
double calc(use a)
{
    int i;double j=0;
    for (i=1;i<=n;++i) j+=dis(a,ai[i])*ai[i].gi;
    if (j<minn){minn=j;ans=a;} return j;
}
void work(double t)
{
    use a,now=ans;int i;double j;
    while(t>0.01)
    {
        a.x=now.x+t*(ran()*2-1);
        a.y=now.y+t*(ran()*2-1);
        j=calc(now)-calc(a);
        if (j>0||exp(j/t)>ran()) now=a;
        t*=0.980;
    }
    for (i=1;i<=1000;++i)
    {
        a.x=ans.x+t*(ran()*2-1);
        a.y=ans.y+t*(ran()*2-1);
        calc(a);
    }
}
int main()
{
    int i,j;scanf("%d",&n);srand(23333);
    for (i=1;i<=n;++i)
    {
        scanf("%lf%lf%lf",&ai[i].x,&ai[i].y,&ai[i].gi);
        ans.x+=ai[i].x*1.0;ans.y+=ai[i].y*1.0;
    }ans.x/=n;ans.y/=n;
    work(500000);printf("%.3f %.3f\n",ans.x,ans.y);
}
View Code

 

爬山算法 模拟退火

标签:

原文地址:http://www.cnblogs.com/Rivendell/p/4780434.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!