RIA算法解决最小覆盖圆问题
一.概念引入
最小包围圆问题:对于给定的平面上甩个点所组成的一个集合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算法解决最小覆盖圆问题的更多相关文章
- GiftWrapping算法解决二维凸包问题
一.问题描述 凸集(Convex Set): 任意两点的连线都在这个集合内的集合就是一个凸集. ⒈对于一个集合D,D中任意有限个点的线性组合的全体称为D的凸包. ...
- 题目1437:To Fill or Not to Fill:贪心算法解决加油站选择问题(未解决)
//贪心算法解决加油站选择问题 //# include<iostream> # include<stdio.h> using namespace std; # include& ...
- xsank的快餐 » Python simhash算法解决字符串相似问题
xsank的快餐 » Python simhash算法解决字符串相似问题 Python simhash算法解决字符串相似问题
- 详解zkw算法解决最小费用流问题
网络流的一些基本概念 很多同学建立过网络流模型做题目, 也学过了各种算法, 但是对于基本的概念反而说不清楚. 虽然不同的模型在具体叫法上可能不相同, 但是不同叫法对应的思想是一致的. 下面的讨论力求规 ...
- 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 ...
- Hash算法解决冲突的方法
https://blog.csdn.net/feinik/article/details/54974293 Hash算法解决冲突的方法一般有以下几种常用的解决方法1, 开放定址法:所谓的开放定址法就是 ...
- hdu1533 Going Home km算法解决最小权完美匹配
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- 【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)
喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 文章声明 此文章部分资料和代码整合自网上,来源太多已经无法查明出处,如侵犯您的权利,请联系我删除. 01 什么是旅行商问题(TS ...
- 如何理解C4.5算法解决了ID3算法的偏向于选择取值较多的特征问题
如何理解C4.5算法解决了ID3算法的偏向于选择取值较多的特征问题 考虑一个极端情况,某个属性(特征)的取值很多,以至于每一个取值对应的类别只有一个.这样根据\[H(D) - H(D|A)\]可以得知 ...
随机推荐
- We7——很有意思的一个开源CMS
目前做门户.做网站,基本上都需要用到一个系统,那就是CMS内容管理系统:现在开源产品有很多,笔者也是从事这个行业的,国内的各大CMS提供商基本上都试用过,今天向大家推荐一款很有意思的产品——We7CM ...
- zoom 用法
from: http://www.jb51.net/css/40285.html 其实Zoom属性是IE浏览器的专有属性,Firefox等浏览器不支持.它可以设置或检索对象的缩放比例.除此之外,它还有 ...
- Oracle RAC备份异机单实例恢复演练
本文只节选了操作方案的部分章节: 3. 操作步骤 3.1. 异机单实例Oracle数据库软件安装 在异机上进行单实例Oracle数据库软件安装.该步骤过程不再本文中重复描述,如果对安装过程存在疑问 ...
- Jfinal 入门
Jfinal 入门 IDE----->IDEA 新建项目 新建web项目 添加maven特性 方便导入jar包,不用一个个导入了 配置pom.xml <dependencies> & ...
- 聊聊iOS开发中耳机的那点事(监听耳机拔插、耳机线控)-b
如果说一个项目出现的最重大的事故,那无疑就是开发人员使用了不可控的元素. 前言 iOS开发当中有关于视音频播放的开发不在少数,用户时常会使用到一种输出设备,那就是"耳机",这一篇博 ...
- javascript 闭包暴露句柄和命名冲突的解决方案
暴露 最近在琢磨前端Js开源项目的东西,然后就一直好奇他们是怎么句柄暴露出来的,特整理一下两种方法. 将对象悬挂到window下面. 不使用var进行变量声明.下面上代码: (function(win ...
- JS数组整理
1. 检测数组的方法: 1. instanceof[操作符]: var arr = []; console.log(arr instanceof Array);//true 1. instanceof ...
- 什么是实时应用程序自我保护(RASP)?
什么产品可以定义为 RASP? RASP 英文为 Runtime application self-protection,它是一种新型应用安全保护技术,它将保护程序想疫苗一样注入到应用程序和应用程序融 ...
- 在Qt中使用sleep(包含为win and *nix下sleep函数的实现及用法)
http://blog.csdn.net/tingsking18/article/details/5304254 关于sleep函数,我们先来看一下他的作用:sleep函数是使调用sleep函数的线程 ...
- 【Python Network】权威域名服务器级联查询
如果PyDNS库,跳过本地名称服务器,直接向权威名称服务器查询.如baidu.com查询.com域名服务器,并从各个域名服务器中查询下一即域名,并输出相关信息. #! /usr/bin/env pyt ...