poj 2420,模拟退火算法,费马点

题目链接:http://poj.org/problem?id=2420

题意:给n个点,找出一个点,使这个点到其他所有点的距离之和最小,也就是求费马点。

参考链接:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

这一篇文章写的很好,我这个小白都有一点小明白了。

记一下笔记:

模拟退火: 就是在一定范围内接受一些不是最优的解,来跳出局部最优,靠近整体最优。

贴一下伪代码:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<deque>
#include<functional>
#include<iterator>
#include<set>
#include<utility>
#include<stack>
#include<queue>
#include<iomanip>
#include<cmath>

using namespace std;

#define N 1005
#define eps 1e-8
#define INF 1e99
#define delta 0.98
#define T 100

int dx[4] = {0,0,-1,1};
int dy[4] = {-1,1,0,0};

struct Point
{
    double x,y;
} p[N];

double dist (Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

double GetSum(Point p[],int n,Point t)
{
    double ans = 0;
    while(n--)
    {
        ans+=dist(p[n],t);
    }
    return ans;
}

double Search(Point p[],int n)
{
    Point s = p[0];
    double t = T;
    double ans = INF;
    while(t>eps)
    {
        bool flag = 1;
        while(flag)
        {
            flag = 0;
            for(int i=0; i<4; i++)
            {
                Point z;
                z.x = s.x + dx[i]*t;
                z.y = s.y + dy[i]*t;
                double tp = GetSum(p,n,z);
                if(ans>tp)
                {
                    ans = tp;
                    s = z;
                    flag = 1;
                }
            }
        }
        t*=delta;
    }
    return ans;
}

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        printf("%.0lf\n",Search(p,n));
    }
    return 0;
}

时间: 2024-10-15 04:10:31

poj 2420,模拟退火算法,费马点的相关文章

POJ 1379 模拟退火算法

求规定平面上一点到已知点的最小距离最大的点. 模拟退火的流程是,随机构造几组解作为初始解空间,每次对当前解空间进行随机扩展,若发现更优解则替换. 进行的次数由参数人为控制,而随机扩展的幅度也是随着次数逐渐减小的. #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<cmath> #include<string> #include&

POJ 2420 模拟退火

链接: http://poj.org/problem?id=2420 题意: 给出n个点,找到一个点,使得它到所有的点的距离最小. 题解: 最近要做一个排课系统,需要用到模拟退火算法,之前虽然了解过这个算法,但是没有写过题.就先在POJ上找了一道学习一下. 代码: 1 #include <iomanip> 2 struct Point { double x, y; }; 3 4 const double eps = 1e-8; //搜索条件阀值 5 const double T = 100;

SDOI 2010--古代猪文(Lucas算法&amp;费马小定理&amp;中国剩余定理)

发现几乎每次数论题洛谷总是让我TLE一个点.... 附图: 最后那个点优化了很久终于过了.... 题意 iPig在大肥猪学校图书馆中查阅资料,得知远古时期猪文文字总个数为N.当然,一种语言如果字数很多,字典也相应会很大.当时的猪王国国王考虑到如果修一本字典,规模有可能远远超过康熙字典,花费的猪力.物力将难以估量.故考虑再三没有进行这一项劳猪伤财之举.当然,猪王国的文字后来随着历史变迁逐渐进行了简化,去掉了一些不常用的字. iPig打算研究古时某个朝代的猪文文字.根据相关文献记载,那个朝代流传的猪

POJ 2420 A Star not a Tree? (计算几何-费马点)

A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3435   Accepted: 1724 Description Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10base2 (coaxial) cables that allow you

poj 3990 Fermat Point in Quadrangle 凸包和费马点

题意: 求一个四边形的费马点. 分析: 模拟退火要么超时要么wa,这题的数据就是不想让随机算法过的..其实四边形的费马点很简单,如果是凸四边形的话费马点是对角线交点,如果是凹四边形费马点是凹点.但题目给的四个点顺序是不确定的,所以要先求下凸包. 代码: //poj 3990 //sep9 #include <iostream> #include <cmath> #include <algorithm> using namespace std; struct Point

poj1379+POJ2420+hdu3932(最短距离+费马点+模拟淬火算法)

Run Away Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5632   Accepted: 1729 Description One of the traps we will encounter in the Pyramid is located in the Large Room. A lot of small holes are drilled into the floor. They look complet

【模板】模拟退火 费马点以及最小球覆盖

最近学了一波模拟退火.个人感觉,就是随机算法,然后我们的目标点,一开始温度T高的时候会移动的剧烈,T小的时候移动的缓和(所以这就是为什么每一次移动的距离都是乘T).然后真正的模拟退火是如果当前的tem比ans优,那就毫不犹豫地接受,否则则以一定概率接受.也就是那个exp(dE/T)> rand 那个. 然后还有爬山算法,就是只会一直找更优解,不接受差解,具体就是在模拟退火基础上,一直找最优解,找不到就降温(所以会陷入局部最优解的坑).在网上嫖了一份代码(https://blog.csdn.net

HDU 1098 Ignatius&#39;s puzzle 费马小定理+扩展欧几里德算法

题目大意: 给定k,找到一个满足的a使任意的x都满足 f(x)=5*x^13+13*x^5+k*a*x 被65整除 推证: f(x) = (5*x^12 + 13 * x^4 + ak) * x 因为x可以任意取 那么不能总是满足 65|x 那么必须是 65 | (5*x^12 + 13 * x^4 + ak) 那么就是说 x^12 / 13 + x^4 / 5 + ak / 65 正好是一个整数 假设能找到满足的a , 那么将 ak / 65 分进x^12 / 13 + x^4 / 5中得到

POJ SETI 高斯消元 + 费马小定理

http://poj.org/problem?id=2065 题目是要求 如果str[i] = '*'那就是等于0 求这n条方程在%p下的解. 我看了网上的题解说是高斯消元 + 扩展欧几里德. 然后我自己想了想,就用了高斯消元 + 费马小定理.因为%p是质数,所以很容易就用上了费马小定理,就是在除法的时候用一次就好了.还有就是两个模数相乘还要模一次. #include <cstdio> #include <cstdlib> #include <cstring> #inc