poj1379——Run Away

模拟退火算法。

基本步骤

<!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

其中 delta 取 (max(矩行边长))/sqrt(m).算法的正确性与L N的取值有关系。

来源于《浅谈随机化思想在几何问题中的应用》 By顾研 <!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

参考:http://boatswain.info/lovers/wordpress/?p=117

#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define N 30 #define L 30 #define esp 1e-2//即1/100 与所求精度有关 class node { public: double x,y,d; node() { x=y=d=0.0; } }rp[10086],date[10086]; int m,X,Y; double delta; double mindate(double a,double b) { if(a>b) return b; return a; } double dist(double sx,double sy,double x,double y) { return sqrt((sx-x)*(sx-x)+(sy-y)*(sy-y)); } void randrp()//随机撒点 即候选解 { int i,j; for(i=0;i<N;i++) { rp[i].x =rand()%X+1; rp[i].y =rand()%Y+1; rp[i].d =1e10; for(j=0;j<m;j++) { rp[i].d =mindate(rp[i].d ,dist(rp[i].x,rp[i].y,date[j].x,date[j].y )); } } } int main() { int i,j,t; cin>>t; while(t--) { cin>>X>>Y>>m; for(i=0;i<m;i++) cin>>date[i].x>>date[i].y; randrp(); delta=(X>Y?X:Y)/sqrt((double)m)+1; while(delta>esp) { for(i=0;i<N;i++) { for(j=0;j<=L;j++) { node now; double dis; double phi=rand(); now.x=rp[i].x +cos(phi)*delta;//试图产生新的优解 now.y=rp[i].y +sin(phi)*delta; if(now.x>=0&&now.x<=X&&now.y>=0&&now.y<=Y) { now.d =1e10; for(int k=0;k<m;k++) { now.d =mindate(now.d ,dist(now.x,now.y,date[k].x,date[k].y)); } if(now.d >rp[i].d ) rp[i]=now; } } } delta*=0.65; } double ans=-1; int right; for(i=0;i<N;i++) if(rp[i].d >ans) { ans=rp[i].d; right=i; } printf("The safest point is (%.1f, %.1f).\n",rp[right].x ,rp[right].y); } return 0; }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值