一.概念引入

        最小包围圆问题:对于给定的平面上甩个点所组成的一个集合P,求出P的最小包围圆,即包含P中所有点、半径最小的那个圆。也就是求出这个最小
包围圆的圆心位置和半径。

        下面是若干性质。

  • 有限点集P的最小包围圆是唯一的。这里约定,若P中只有一个点v,则最小包围圆是退化的,其半径为0,圆心为点v。
  • 非退化最小包围圆可以由2个或者3个边界点定义。边界上只有两个点,则必定是直径两端,其它点都在圆内部,这个咱就不证明了。
  • 点集P中,距离最大的2个点A、B不一定都在边界上,但是必有d≥|AB|,笔者认为这点很重要。

  • 直角三角形或钝角三角形的3个顶点的最小包围圆是以最长边为直径的圆;锐角三角形3个顶点的最小包围圆是三角形的外接圆。
  • 新加入点一定在圆上

二.算法实现

           加上shuffle后,ZOJ1450第二组数据结果不稳定,不加的话全部正确,不过两者都还是WA,莫非求圆心也没错(水平竖直斜向都可以求出),别人的C++的都AC(用了random_shuffle()函数了,原来判断点在圆心内写错了,网上找不到java代码,不管了……

package a;
import java.util.Random;
import java.util.Scanner; /*
* hdu只有500点,可以直接两点间最大距离暴力试试
*/
public class HDU3007 { public static void main(String[] args) {
new RIA().go();
}
} class Point {
double x;
double y; public Point() {
this.x = 0;
this.y = 0;
}
} class Line {
Point a;
Point b; public Line() {
this.a = new Point();
this.b = new Point();
}
public Line(Point a,Point b) {
this.a = a;
this.b = b;
} //求两直线的交点,斜率相同的话res=u.a
Point intersection(Line u,Line v){
Point res = u.a;
double t = ((u.a.x-v.a.x)*(v.b.y-v.a.y)-(u.a.y-v.a.y)*(v.b.x-v.a.x))
/((u.a.x-u.b.x)*(v.b.y-v.a.y)-(u.a.y-u.b.y)*(v.b.x-v.a.x));
res.x += (u.b.x-u.a.x)*t;
res.y += (u.b.y-u.a.y)*t;
return res;
} //三角形外接圆圆心(外心)
// Point center(Point a,Point b,Point c) {
// //加上这个才没有编译器提示未初始化,因为new所以也写了构造方法
// Line u = new Line(),v = new Line();
// u.a.x=(a.x+b.x)/2;
// u.a.y=(a.y+b.y)/2;
// u.b.x=u.a.x+(u.a.y-a.y);
// u.b.y=u.a.y-(u.a.x-a.x);
// v.a.x=(a.x+c.x)/2;
// v.a.y=(a.y+c.y)/2;
// v.b.x=v.a.x+(v.a.y-a.y);
// v.b.y=v.a.y-(v.a.x-a.x);
// return intersection(u,v);
// }
Point center(Point a,Point b,Point c) {
Point ret = new Point();
double a1=b.x-a.x, b1=b.y-a.y, c1=(a1*a1+b1*b1)/2;
double a2=c.x-a.x, b2=c.y-a.y, c2=(a2*a2+b2*b2)/2;
double d = a1*b2 - a2*b1;
ret.x = a.x + (c1*b2-c2*b1)/d;
ret.y = a.y + (a1*c2-a2*c1)/d;
return ret;
}
} class RIA {
int n;
double x;
double y; public void go() {
Scanner sc = new Scanner(System.in);
while(true) {
n = sc.nextInt();
if(0==n)
break;
Point point[] = new Point[n];
for(int i=0; i<n; i++) {//不加的话空指针异常
point[i] = new Point();
}
for(int i=0; i<n; i++) {
x = sc.nextDouble();
y = sc.nextDouble();
point[i].x = x;
point[i].y = y;
}
//shuffle(point);
solve(point);
}
} private void shuffle(Point[] point) { for(int i=0; i<point.length; i++) {
//Random r = new Random();
//int j = r.nextInt(point.length);
int j = (int)(Math.random()*point.length);
if(i!=j) {
Point temp = point[i];
point[i] = point[j];
point[j] = temp;
}
}
} private void solve(Point[] point) { Point circle = point[0];
double r = 0; for(int i=1; i<n; i++) {
double dis = distance(circle, point[i]);
if(Double.compare(dis, r)<=0) {
continue;
}
circle = point[i];
r = 0;
for(int j=0; j<i; j++) {
dis = distance(circle, point[j]);
if(Double.compare(dis, r)<=0) {
continue;
}
circle.x = (point[j].x + point[i].x)/2;
circle.y = (point[j].y + point[i].y)/2;
r = distance(circle, point[j]); for(int k=0; k<j; k++) {
dis = distance(circle, point[k]);
if(Double.compare(dis, r)<=0) {
continue;
}
Line line = new Line();
circle = line.center(point[i],point[j],point[k]);
r = distance(point[k], circle);
} } }
//没有lf只说
System.out.println(String.format("%.2f", circle.x) +
" "+String.format("%.2f", circle.y)+
" "+String.format("%.2f", r));
//这样不行,若是初试不足三位,那么输出就不够三位
// System.out.println((double)Math.round(circle.x*100)/100 +
// " "+(double)Math.round(circle.y*100)/100+
// " "+(double)Math.round(r*100)/100); } public double distance(Point p1, Point p2) {
return (Math.hypot((p1.x - p2.x), (p1.y - p2.y)));
}
}

三.若干思考

        RIA算法叫随机增量法,加入随机性后复杂度是线性的(表示目前不太理解),昨晚又想了想,第一层循环是产生新加入的点,由性质知该点必须在圆上,所以三层循环里每层都有point[i]去组成圆(第一层中是退化的);

        第一层中为什么半径是0呢?和圆心是point[i]一样,笔者认为主要是为让第二层一定进行下去(略过if判断),或者就认为此时只有一个点是退化圆。

        如何保证最小?因为每次都是最小的(看倒数第二条性质),所以结果是最小的。

四.浮点数

        Double.compare(p,q),若是和0比,下面也可以:

double exp = 1e-10;
if (Math.abs(val1 - val2)>-1*exp && Math.abs(val1 - val2)<exp) {
//do things
}

RIA算法解决最小覆盖圆问题的更多相关文章

  1. GiftWrapping算法解决二维凸包问题

    一.问题描述 凸集(Convex Set): 任意两点的连线都在这个集合内的集合就是一个凸集.             ⒈对于一个集合D,D中任意有限个点的线性组合的全体称为D的凸包.         ...

  2. 题目1437:To Fill or Not to Fill:贪心算法解决加油站选择问题(未解决)

    //贪心算法解决加油站选择问题 //# include<iostream> # include<stdio.h> using namespace std; # include& ...

  3. xsank的快餐 » Python simhash算法解决字符串相似问题

    xsank的快餐 » Python simhash算法解决字符串相似问题 Python simhash算法解决字符串相似问题

  4. 详解zkw算法解决最小费用流问题

    网络流的一些基本概念 很多同学建立过网络流模型做题目, 也学过了各种算法, 但是对于基本的概念反而说不清楚. 虽然不同的模型在具体叫法上可能不相同, 但是不同叫法对应的思想是一致的. 下面的讨论力求规 ...

  5. SA:利用SA算法解决TSP(数据是14个虚拟城市的横纵坐标)问题——Jason niu

    %SA:利用SA算法解决TSP(数据是14个虚拟城市的横纵坐标)问题——Jason niu X = [16.4700 96.1000 16.4700 94.4400 20.0900 92.5400 2 ...

  6. Hash算法解决冲突的方法

    https://blog.csdn.net/feinik/article/details/54974293 Hash算法解决冲突的方法一般有以下几种常用的解决方法1, 开放定址法:所谓的开放定址法就是 ...

  7. hdu1533 Going Home km算法解决最小权完美匹配

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  8. 【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)

    喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 文章声明 此文章部分资料和代码整合自网上,来源太多已经无法查明出处,如侵犯您的权利,请联系我删除. 01 什么是旅行商问题(TS ...

  9. 如何理解C4.5算法解决了ID3算法的偏向于选择取值较多的特征问题

    如何理解C4.5算法解决了ID3算法的偏向于选择取值较多的特征问题 考虑一个极端情况,某个属性(特征)的取值很多,以至于每一个取值对应的类别只有一个.这样根据\[H(D) - H(D|A)\]可以得知 ...

随机推荐

  1. WPF从入门到放弃系列第一章 初识WPF

    什么是WPF WPF(Windows Presentation Foundation)是微软推出的基于Windows Vista的用户界面框架,属于.NET Framework 3.0的一部分.它提供 ...

  2. Java琐记

    svn项目倒入,所选的文件夹一定是src上面以及的:然后eclipse会自动创建一个项目,项目名称就是src上级文件夹的名称:然后会按照路径下的文档结构如导入到eclipse的结构中: 被标记为// ...

  3. 解释型语言和编译型语言的不同以及Python如何运行

    计划写关于Python中如何实现属性管理.函数(或类方法)管理.类管理的几篇成系列的文章. 而这篇文章写在这个系列之前,希望对后面几篇文章的理解有所帮助. 老实说,我也是在网上搜索了一些资料才写的这篇 ...

  4. 判断js中各种数据的类型方法之typeof与0bject.prototype.toString讲解

    提醒大家,Object.prototype.toString().call(param)返回的[object class]中class首字母是大写,像JSON这种甚至都是大写,所以,大家判断的时候可以 ...

  5. WCF 消息压缩性能问题及解决方法

    最近使用WCF作为通迅框架开发一套信息系统,系统使用传统C/S框架,系统有可能会部署在互联网上,因此决定对传输的数据进行GZIP压缩,原来在使用.NET Remoting时,可以使用插入自定义的Cha ...

  6. php截取小时和分钟,在进行和其它时间段的比较

    用php截取时间的小时和分钟,然后判断这个时间是不是在 8:00到11:30之间,用php应该怎么写? date_default_timezone_set("Asia/Shanghai&qu ...

  7. LINUX关闭防火墙(转载)

    (1) 重启后永久性生效: 开启:chkconfig iptables on 关闭:chkconfig iptables off (2) 即时生效,重启后失效: 开启:service iptables ...

  8. 李洪强iOS开发本人集成环信的经验总结_02_基本配置

     李洪强iOS开发本人集成环信的经验总结_02_基本配置 来到APPdelegate中做一些配置 01 - 导入头文件 02 - 在didFinishLaunchingWithOptions用法总结 ...

  9. SPRING IN ACTION 第4版笔记-第六章RENDERING WEB VIEWS-003- SPRING的GENERAL TAG LIBRARY简介及用<s:message>和ReloadableResourceBundleMessageSource实现国际化

    一. SPRING支持的GENERAL TAG LIBRARY 1. 二.用<s:message>和ReloadableResourceBundleMessageSource实现国际化 1 ...

  10. JAVA与C++的区别和联系

    这篇总结的貌似不错: http://wenku.baidu.com/link?url=VixkWGl0BzUkmceaDJnQeUhzKEIex6poGaKKvMTP87P8a7HTmS5uIi87I ...