POJ 1379 模拟退火

模拟退火算法,很久之前就写过一篇文章了。双倍经验题(POJ 2420)

题意:

在一个矩形区域内,求一个点的距离到所有点的距离最短的那个,最大。

这个题意,很像二分定义,但是毫无思路,也不能暴力枚举,那就模拟退火。

#include <stdio.h>
#include <math.h>
#include <algorithm>

using namespace std;

const int maxn = 1005;

int X,Y,M;
int Kase;

struct Node {
    double x,y;
}nodes[maxn];

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

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

double calc(Node p) {
    double ret = 0x3f3f3f3f;
    for(int i = 0; i < M; i++)
        ret = min(ret,dist(p,nodes[i]));
    return ret;
}

int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d",&Kase);
    while(Kase--) {
        scanf("%d%d%d",&X,&Y,&M);

        for(int i = 0; i < M; i++)  scanf("%lf%lf",&nodes[i].x,&nodes[i].y);

        Node s;
        s.x = X/2;
        s.y = Y/2;

        double t = max(X,Y);
        double ansx = X/2;
        double ansy = Y/2;
        double ans = calc(s);

        Node tmp;
        tmp.x = 0;
        tmp.y = 0;
        double anstmp = calc(tmp);
        if(anstmp>ans) {
            ans = anstmp;
            ansx = 0;
            ansy = 0;
        }

        tmp.x = 0;
        tmp.y = Y;
        anstmp = calc(tmp);
        if(anstmp>ans) {
            ans = anstmp;
            ansx = 0;
            ansy = Y;
        }

        tmp.x = X;
        tmp.y = 0;
        anstmp = calc(tmp);
        if(anstmp>ans) {
            ans = anstmp;
            ansx = X;
            ansy = 0;
        }

        tmp.x = X;
        tmp.y = Y;
        anstmp = calc(tmp);
        if(anstmp>ans) {
            ans = anstmp;
            ansx = X;
            ansy = Y;
        }

        while(t>1e-8) {
            bool flag = true;
            while(flag) {
                flag = false;
                for(int i = 0; i < 4; i++) {
                    Node v;
                    v.x = s.x + dx[i]*t;
                    v.y = s.y + dy[i]*t;
                    if(v.x>X||v.y>Y||v.x<0||v.y<0) continue;

                    double tp = calc(v);

                    if(tp>ans) {
                        ans = tp;
                        flag = true;
                        ansx = v.x;
                        ansy = v.y;
                        s = v;
                    }
                }
            }
            t = t*0.98;
        }

        printf("The safest point is (%.1f, %.1f).\n",ansx,ansy);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/TreeDream/p/8391511.html

时间: 2024-10-13 10:27:30

POJ 1379 模拟退火的相关文章

POJ 1379 模拟退火算法

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

POJ 1379 模拟退火法

Run Away Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5631   Accepted: 1728 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

POJ 1379

模拟退火算法. 随机MAX个点,然后,退火移动,选取距离所有点中最短中最长者即可.理解和我上一篇一样. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <time.h> using namespace std; const int MAXN=1010; const int MA

POJ 1379 Run Away 模拟退火

一开始写了一发很快的,发现一会能过一会不能,貌似有点悬,毕竟是随机算法. 后来重写了一发迭代5遍的,基本上把把AC了= = 模拟退火果然是一种不是很靠谱的算法. #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <cstdlib> #include <ctime> using namespace std; const

POJ 1379 Run Away 【基础模拟退火】

题意:找出一点,距离所有所有点的最短距离最大 二维平面内模拟退火即可,同样这题用最小圆覆盖也是可以的. Source Code: //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <fstream> #include <cstring> #include <cm

POJ 1379 (随机算法)模拟退火

题目大意: 给定一堆点,找到一个点的位置使这个点到所有点中的最小距离最大 这里数据范围很小,精度要求也不高,我们这里可以利用模拟退火的方法,随机找到下一个点,如果下一个点比当前点优秀就更新当前点 参考:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html http://wenku.baidu.com/view/0c6b5df5f61fb7360b4c65a9.html 1 #include <cstdio> 2 #includ

poj 1379 Run Away 模拟退火 难度:1

Run Away Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 6482   Accepted: 1993 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

POJ 1379 Run Away

题意:有n个陷阱,在X,Y范围内要求出一个点使得这个点到陷阱的最小距离最大. 思路:模拟退火,随机撒入40个点,然后模拟退火随机化移动. (这题poj坑爹,加了srand(time(NULL))不能交G++,不加srand(time(NULL))又会WA,交了C++不能用acos(-1),只能用3.1415926代替,真是坑爹.) #include<algorithm> #include<cstdio> #include<cmath> #include<cstri

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;