最小圆覆盖

最小圆覆盖。神奇的随机算法。当点以随机的顺序加入时期望复杂度是线性的。
  algorithm:
  A、令Ci表示为前i个点的最小覆盖圆。当加入新点pi时如果pi不在Ci-1里那么pi必定在Ci的边界上。
  B、再从新考虑这样一个问题,Ci为前i个点最小覆盖圆且p在Ci的的边界上!同理加入新点pi时如果p
  i不在Ci-1里那么pi必定在Ci的边界上。这时我们就包含了两个点在这个最小圆的边界上。
  C、再从新考虑这样一个问题,Ci为前i个点最小覆盖圆且有两个确定点再边界上!此时先让
  O(N)的方法能够判定出最小圆。
  analysis:
  现在来分析为什么是线性的。
  C是线性的这是显然的。
   B<-C的过程中。考虑pi 他在园内的概率为 (i-1)/i 。在圆外的概率为 1/i 所以加入pi的期望复杂度为:(1-i)/i*O(1) +(1/i)*O(i) {前者在园内那么不进入C,只用了O(1)。后者进入C用了O(i)的时间}这样分析出来,复杂度实际上仍旧
  是线性的。
  A<-B的过程中。考虑方法相同,这样A<-B仍旧是线性。于是难以置信的最小圆覆盖的复杂度变成了线性的。

struct Point
{
       double x,y;
} point[M];
double Pow(double x)
{
       return x*x;
}
double dist(Point a,Point b)
{
       return sqrt(Pow(a.x-b.x)+Pow(a.y-b.y));
}

void Circle(Point P0,Point P1,Point P2,Point &o)
{

       double a1=P1.x-P0.x,b1=P1.y-P0.y,c1=(Pow(a1)+Pow(b1))/2;
       double a2=P2.x-P0.x,b2=P2.y-P0.y,c2=(Pow(a2)+Pow(b2))/2;
       double d=a1*b2-a2*b1;
       o.x = P0.x + (c1*b2-c2*b1)/d;
       o.y = P0.y + (a1*c2-a2*c1)/d;
}

void MinCircle(Point point[],Point &o,double &r,int n)//点集 圆心存于o,半径r ,n点的个数
{
       random_shuffle(point,point+n);
       int i,j,k;
       o = point[0];
       for(r = 0,i = 1; i < n; ++i)
       {
               if(dist(point[i],o) <= r)continue;
               o = point[i];
               for(r = j = 0; j < i; ++j)
               {
                       if(dist(point[j],o) <= r)continue;
                       o.x = (point[i].x+point[j].x)/2;
                       o.y = (point[i].y+point[j].y)/2;
                       r = dist(o,point[i]);
                       for(k = 0; k < j; ++k)
                       {
                               if(dist(point[k],o)
                               Circle(point[i],point[j],point[k],o);
                               r = dist(o,point[i]);
                       }
               }
       }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值