zoukankan      html  css  js  c++  java
  • POJ2069 最小球覆盖 几何法和退火法

    对这种问题不熟悉的读者 可以先去看一看最小圆覆盖的问题 ZOJ1450

    现在我们来看最小球覆盖问题POJ2069 题目很裸,给30个点 求能覆盖所有点的最小球的半径。

    先给出以下几个事实:

    1.对于一个点,球心就是这个点且半径无穷小。

    2.对于两个点,球心是两个点线段的中点,半径就是线段长度的一半。

    3.对于三个点,三个点构成的平面必为球的大圆,所以球心是三角形的外心,半径就是球心到某个点的距离。

    4.对于四个点,若四个点共面则转化到3,只需考虑某三个点的情况,若四点不共面,四面体可以唯一确定一个外接球。

    5.对于五个及以上点,其最小球必为其中某4个点的外接球(假设不全共面)。

    C(30,4)是可以接受的复杂度。在编程实现的时候,碰到不在球内的点,就让它成为球面上的点,期望复杂度为O(n)。

    -----------------------------------------------------------------------------------------------------------------------------------------------

    以上我们给出了一般的几何解法,但是求三角形外心和四面体的外界球,方程很复杂,代码量也很大,有没有简单的方法呢?

    我们根据以上5个事实,可以知道所谓最小球的球心,它必然处于一个稳定态,也就是与它距离最远的点最多有4个且等距离。

    于是,我们首先任选一个点作为球心,并找到点集中与它距离最远的点,我们让球心靠近最远的点,不断重复此过程,就可以让球心达到稳定态了!此时我们就找到了最小球。

     1 #include <iostream>  
     2 #include<cstdio>  
     3 #include<algorithm>  
     4 #include<cstring>  
     5 #include<cmath>  
     6 using namespace std;  
     7 const double eps=1e-7;  
     8 struct point3D  
     9 {  
    10     double x,y,z;  
    11 } data[35];  
    12 int n;  
    13 double dis(point3D a,point3D b)  
    14 {  
    15     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));  
    16 }  
    17 double solve()  
    18 {  
    19     double step=100,ans=1e30,mt;  
    20     point3D z;  
    21     z.x=z.y=z.z=0;  
    22     int s=0;  
    23     while(step>eps)  
    24     {  
    25         for(int i=0; i<n; i++)  
    26             if(dis(z,data[s])<dis(z,data[i])) s=i;  
    27         mt=dis(z,data[s]);  
    28         ans=min(ans,mt);  
    29         z.x+=(data[s].x-z.x)/mt*step;  
    30         z.y+=(data[s].y-z.y)/mt*step;  
    31         z.z+=(data[s].z-z.z)/mt*step;  
    32         step*=0.98;  
    33     }  
    34     return ans;  
    35 }  
    36 int main()  
    37 { // freopen("t.txt","r",stdin);
    38     double ans;  
    39     while(~scanf("%d",&n),n)  
    40     {  
    41         for(int i=0; i<n; i++)  
    42             scanf("%lf%lf%lf",&data[i].x,&data[i].y,&data[i].z);  
    43         ans=solve();  
    44         printf("%.5f
    ",ans);  
    45     }  
    46     return 0;  
    47 }  
    View Code

     

  • 相关阅读:
    377 TODOMVC:准备工作,配置 vue,列表渲染,添加任务,删除任务,编辑任务 ,Footer 的显示与隐藏
    376 vue指令:v-model (常用),v-text 和 v-html,v-bind (常用),操作样式,v-on,v-for,v-pre,v-once,v-cloak
    375 vue数据双向绑定演示:一个 input + v-model,Object.defineProperty,数据双向绑定的原理简单实现
    374 vue起步
    373 Vue 介绍,框架和库的区别 ,MVC + MVVM
    实现一个vue-router插件
    浅谈react context
    Flutter网络请求与JSON解析
    Vue中组件
    vue数据监听
  • 原文地址:https://www.cnblogs.com/heisenberg-/p/6827790.html
Copyright © 2011-2022 走看看