POJ 2420 模拟退火求费马点

题意求一个多边形的费马点,即到所有顶点距离和最小的那一点。

以前觉得模拟退火好高端的样子,实际就是把点往四个方向移动固定步长,知道不能移动后缩小步长继续移动,也就是随机求一个接近最优并且满足精度的解。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef double diy;
struct point
{
    diy x,y;
    point() {}
    point(diy _x,diy _y):x(_x),y(_y) {}
};
double step[4][2]= {0,1,0,-1,-1,0,1,0};
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 disall(point a,point *g,int n)
{
    int i=0;
    double sum=0;
    while(n--)
        sum+=dis(a,g[i++]);
    return sum;
}
double SAnnealing(point *g,int n)
{
    point t=g[0];
    int flag;
    double ret=disall(t,g,n),st;
    for(st=100; st>1e-1; st*=0.98)
    {
        flag=1;
        while(flag)
        {
            flag=0;
            for(int i=0; i<4; i++)
            {
                point now(t.x+step[i][0]*st,t.y+step[i][1]*st);
                double nowdis=disall(now,g,n);
                if(nowdis<ret)
                    t=now,flag=1,ret=nowdis;
            }
        }
    }
    return ret;
}
int main()
{
    int n;
    point data[105];
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
            scanf("%lf%lf",&data[i].x,&data[i].y);
        printf("%.0f\n",SAnnealing(data,n));
    }
    return 0;
}
时间: 2024-10-18 13:40:24

POJ 2420 模拟退火求费马点的相关文章

费马点推广问题

问题描述 己知一直线y=kx+b两点A.B.求费马点坐标. 解决方案 解决方案二:什么是费马点...解决方案三:直线..?费马点不是求离三个顶点距离之和最小的那个点啊..解决方案四:一个推广,在直线上找出第三点,使三点总距离最短.解决方案五:先随便找一个x,算出对应的y,再算出到另外3点的距离之和.然后初始一个值k,分别计算x=x+k和x=x-k时的距离和,如果其中一个小于x=x时的距离和,则令x=该值,继续迭代.如果2个值都大于x=x时的距离和,则令k=k/2,继续上面的方法,直到达到相应的精

模拟退火求二维费马点

一.概念引入         AC过后,突然想起费马点和最小覆盖圆的圆心有关系吗?答案是没关系,如下图:费马点肯定在等腰梯形内,不是在圆心.         模拟退火算法与初始值无关,算法求得的解与初始解状态S(是算法迭代的起点)无关:模拟退火算法具有渐近收敛性,已在理论上被证明是一种以概率收敛于全局最优解的全局优化算法:模拟退火算法具有并行性.         三角形费马点:如果三角形ABC中有一个角的角度大于等于120, 那么该角的顶点就是费马点:如果三角形ABC的三个角的角度都小于120,

c++-C++用递归方式求费波拉契数列前20项,要求每5个一行

问题描述 C++用递归方式求费波拉契数列前20项,要求每5个一行 用递归方式求费波拉契数列前20项,要求每5个一行 费波拉契数列是指,第一第二项都是1,后面每一项是前两项之和,1,1,2,3,5,8,13,... 解决方案 Long F(int n) {if(n==1||n==2) return(1L); else return(F(n-2)+F(n-1)); } 解决方案二: 方法就是这个,然后自己分行吧 解决方案三: #include using namespace std; int f[2

费马小定理

费马小定理是数论中的一个定理:假如a是一个整数,p是一个质数,那么 如果a不是p的倍数,这个定理也可以写成

求解决-入门小白求解北京2004ACM的Square题

问题描述 入门小白求解北京2004ACM的Square题 入门小白开始啃题,然而啃不动(无奈摊手) 求大神帮忙解答(最好是有解释啦)(?>ω<*?) SquareTime Limit:?1000ms,?Special Time Limit:2500ms,?Memory Limit:32768KBTotal submit users:?177,?Accepted users:?26Problem 10002 :?No special judgementProblem descriptionGiv

poj-Poj 1011 TLE...求大神指教0.0

问题描述 Poj 1011 TLE...求大神指教0.0 enter code here #include#includeusing namespace std;const int maxn = 65;int A[maxn];bool used[maxn];int n;bool cmp(int aint b){ return a > b;}bool ok(int reint lenint length){ if(re == 0 && len == length) return tru

poj 2886 Who Gets the Most Candies?

点击打开poj 2886 思路: 求因子数+单点更新 分析: 1 题目的意思是有n个人构成一个环,刚开始是第k个人先出来.每个人有一个名字和数值A,如果A为正数,那么下一个出去的人是他左边的第A个人,如果是负数那么出去的将是右边的第A个人 2 这么我们要注意一下,因为n个人是围城一圈,那么左边就是顺时针方向,右边就是逆时针方向 3 那么我们就可以来推没一次出去的人的在剩下中是第几个.    假设当前是第k个人出去,并且这个人的值为A,并且剩下有sum个人    A > 0 , 因为这个人出去了,

求高精度幂

POJ 1001 – Exponentiation 求高精度幂 时间限制:500毫秒            内存限制:10000KB [问题描述] 对数值很大.精度很高的数进行高精度计算是一类十分常见的问题.比如,对国债进行计算就是属于这类问题. 现在要你解决的问题是:对一个实数R(0.0 < R < 99.999),要求写出程序精确计算R的n次方(Rn),其中n是整数并且0 < n <= 25. [输入格式] 输入包括多组R和n.R的值占第1到第6列,n的值占第8和第9列. [输

NOD 1171 x^2+y^2=N

1171 . 两个数的平方和 V2 时间限制:1 秒 空间限制:65536 KB 分值: 1280 给出一个整数N,将N表示为2个整数i j的平方和(i <= j),如果有多种表示,按照i的递增序输出. 例如:N = 130,130 = 3^2 + 11^2 = 7^2 + 9^2 (注:3 11同11 3算1种) Input 一个数N(1 <= N <= 10^18) Output 共K行:每行2个数,i j,表示N = i^2 + j^2(0 <= i <= j). 如果