POJ2420模拟退火

#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define inf 0x3f3f3f
#define num 30
#define tim 10
#define data 0.7
#define RD 1000
#define MIN 0.001 复杂度X * NUM * TIM * n; X为T到MIN的循环次数,由deta决定
using namespace std;
struct mat
{
    double x,y,dis;
   mat(){}     //这里初始化列表要这样搞,下面就可以直接用mat ans = (xxx,xxx)的形式了.
    mat(double x,double y):x(x),y(y){}
};
mat test[100],ans[num],a,b;
int n;
double distanc(mat a ,mat b)//这里吐血啊.最开始是distance一直不知道为什么爆很多错。

{                                            //就是那种谈出新的框框那种,后来丘哥帮我查出来是distance貌似是

                                             //库函数

    return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
}
double Getdouble()//随机产生一个0-1的数据
{
    return  (rand()%(RD+1))*1.0/RD;
}
double judge(mat a)//对每个点计算到其他点的距离
{
    double s;
    s = 0;
    for(int f = 0 ; f < n ; f++)
    {
        if(distanc(a,test[f]) > s)
         s += distanc(a,test[f]);
    }
    return s;
}
mat Getrand(mat a ,mat b)
{
    mat z;
    z.x = a.x + (b.x-a.x)*Getdouble();//由getdouble产生的随机数据来使得ans是全部点形成的矩形
    z.y = a.y + (b.y-a.y)*Getdouble();//方框里面的一些随机点.
    z.dis = judge(z);
    return z;
}
void change(double T)//主要的模拟退火过程
{
    mat c,d,tmp;
    for(double t = T ; t >= MIN ; t*=data)//每次变化的步长,data是数据压缩
    {
        for(int i = 0 ; i < num ; i++)
        {
            for(int j = 0 ; j < tim ; j++)//对每个点进行tim次随机测试
            {
                c.x = ans[i].x-t ;
                c.y = ans[i].y-t ;
                d.x = ans[i].x+t ;
                d.y = ans[i].y+t ;
                tmp = Getrand(c,d);
                if(tmp.dis<ans[i].dis)
                  ans[i] = tmp;
            }
        }
    }
}
int main()
{
    while(scanf("%d",&n) != EOF)
    {
        double res;
        a.x = inf;a.y = inf;
        b.x = -inf;b.y = -inf;
        for(int i = 0 ; i < n ; i++)
        {
            scanf("%lf%lf",&test[i].x,&test[i].y);
            if(a.x > test[i].x)a.x = test[i].x;
            if(a.y > test[i].y)a.y = test[i].y;
            if(b.x < test[i].x)b.x = test[i].x;
            if(b.y < test[i].y)b.y = test[i].y;
        }
        for(int i = 0 ; i < num ; i++)
          {
              ans[i] = Getrand(a,b);
          }
          res = inf ;
        change(max(b.y-a.y,b.x-a.x));
        for(int i = 0 ; i < num ; i++)
        {
            if(res > ans[i].dis);
              res = ans[i].dis;
        }
        printf("%.0f\n",res);//最后这里比较吐血啊..到现在还不知道为什么%lf输出为什么是错误的。
    }                                 //只是最后看了下别人的是f输出,改了就过了。郁闷!
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值