zoukankan      html  css  js  c++  java
  • Poj1379+poj 2539(模拟退火

    题目:在矩形中有若干个点,求一个点使得所有点到该点的最小距离最大。

    思路:这个是2008年顾研论文上的例题,可以比较简单地用模拟退火算法求解。所谓模拟退火就是先随机出若干个点,然后以某一特定步长尝试周围的解,而后逐渐缩小步长,知道步长小于特定值,跳出。这个算法虽然简单易行,但是其正确性并不是非常有保障,(不合理的随机方法可能会降低到达正确解的概率),而且几个主要参数的选取也主要看经验,毕竟对于一个随机化算法做出像论文中一样的严格评估还是比较困难的。。。。所以说即使实现完全正确,能否通过有时也是玄学的领域。。。。。尤其对于不太适合随机化的题。

    ps:poj不能用time,一调用就re,查了一个多小时错才发现。。。。以后不用time了。。。

    /*
    * @author:  Cwind
    * http://www.cnblogs.com/Cw-trip/
    * 蒟蒻只能做几个水题。。
    */
    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <functional>
    #include <set>
    #include <cmath>
    using namespace std;
    #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define fs first
    #define se second
    #define sq(x) (x)*(x)
    #define eps (1e-3)
    #define IINF (1<<29)
    #define LINF (1ll<<59)
    #define FINF (1e100)
    #define INF 1000000000
    const double pi=acos(-1.0);
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> P;
    
    inline double dis(double x1,double y1,double x2,double y2){
        return sqrt(sq(x1-x2)+sq(y1-y2));
    }
    int T;
    int X,Y,M;
    const int L=30;
    double zx[1005],zy[1005];
    int main(){
        freopen("/home/files/CppFiles/in","r",stdin);
        srand(rand()%100);
        cin>>T;
        while(T--){
            cin>>X>>Y>>M;
            double delta=max(X,Y)/sqrt(M*1.0)+1,pos[30][2],d[30];
            for(int i=0;i<M;i++){
                double x,y;
                scanf("%lf%lf",&x,&y);
                zx[i]=x,zy[i]=y;
            }
            for(int i=0;i<30;i++){
                pos[i][0]=(rand()%(1000+1)/1000.0*X);
                pos[i][1]=(rand()%(1000+1)/1000.0*Y);
                d[i]=FINF;
                for(int j=0;j<M;j++){
                    d[i]=fmin(d[i],dis(pos[i][0],pos[i][1],zx[j],zy[j]));
                }
            }
            while(delta>eps){
                for(int i=0;i<30;i++){
                    for(int j=0;j<L;j++){
                        double rd=rand();
                        double dx=pos[i][0]+cos(rd)*delta,dy=pos[i][1]+sin(rd)*delta;
                        if(dx>X||dx<0||dy>Y||dy<0) continue;
                        double md=FINF;
                        for(int k=0;k<M;k++){
                            md=fmin(md,dis(dx,dy,zx[k],zy[k]));
                        }
                        if(md>d[i]){
                            pos[i][0]=dx;
                            pos[i][1]=dy;
                            d[i]=md;
                        }
                    }
                }
                delta*=0.8;
            }
            double ans=0;
            int ansp=0;
            for(int i=0;i<30;i++){
                if(ans<d[i]){
                    ans=d[i];
                    ansp=i;
                }
            }
            printf("The safest point is (%.1f, %.1f).
    ",pos[ansp][0],pos[ansp][1]);
        }
        return 0;
    }
    View Code

     poj2539

    题目:求使得一点到其他各点距离之和最小的点。

    思路:和上题一样的写法,很顺利的1a了。。

    /*
    * @author:  Cwind
    * http://www.cnblogs.com/Cw-trip/
    * 蒟蒻只能做几个水题。。
    */
    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <functional>
    #include <set>
    #include <cmath>
    using namespace std;
    #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define fs first
    #define se second
    #define sq(x) (x)*(x)
    #define eps (1e-3)
    #define IINF (1<<29)
    #define LINF (1ll<<59)
    #define FINF (1e100)
    #define INF 1000000000
    const double pi=acos(-1.0);
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> P;
    
    inline double dis(double x1,double y1,double x2,double y2){
        return sqrt(sq(x1-x2)+sq(y1-y2));
    }
    const int maxp=50;
    const int maxx=10000;
    int N;
    double c[105][2];
    double p[maxp][2],d[maxp];
    double delta=5000;
    int L=30;
    double a=0.8;
    int main(){
        freopen("/home/files/CppFiles/in","r",stdin);
        srand(rand()%1000);
        cin>>N;
        for(int i=0;i<N;i++){
            scanf("%lf%lf",&c[i][0],&c[i][1]);
        }
        for(int i=0;i<maxp;i++){
            p[i][0]=(rand()%1001)/1000.0*maxx;
            p[i][1]=(rand()%1001)/1000.0*maxx;
            double sdis=0;
            for(int j=0;j<N;j++){
                sdis+=dis(p[i][0],p[i][1],c[j][0],c[j][1]);
            }
            d[i]=sdis;
        }
        while(delta>eps){
            for(int i=0;i<maxp;i++){
                for(int j=0;j<L;j++){
                    double rd=rand();
                    double dx=p[i][0]+cos(rd)*delta,dy=p[i][1]+sin(rd)*delta;
                    double sdis=0;
                    for(int k=0;k<N;k++){
                        sdis+=dis(dx,dy,c[k][0],c[k][1]);
                    }
                    if(sdis<d[i]){
                        p[i][0]=dx;
                        p[i][1]=dy;
                        d[i]=sdis;
                    }
                }
            }
            delta*=a;
        }
        double ans=1e100;
        for(int i=0;i<maxp;i++){
            ans=fmin(d[i],ans);
        }
        printf("%.0f",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    JSP中自动刷新
    JSP点击计数器
    JSP页面重定向
    JSP处理日期
    Mybatis Generator生成数据库自带的中文注释
    GMT与Etc/GMT地区信息的时区转换
    《Redis入门指南》第2版 读书笔记
    ConcurrentHashMap
    应用服务器性能优化 之 消息队列(MQ:Message Queue)
    TabLayout让Fragment在ViewPager中的滑动切换更优雅
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/4797427.html
Copyright © 2011-2022 走看看