Java实现凸包问题
1 问题描述
给定一个平面上n个点的集合,它的凸包就是包含所有这些点的最小凸多边形,求取满足此条件的所有点。
另外,形象生动的描述:
(1)我们可以把这个问题看作如何用长度最短的栅栏把n头熟睡的老虎围起来。
(2)也可以这样看:请把所讨论的点想象成钉在胶合板上的钉子,胶合板代表平面。撑开一根橡皮筋圈,把所有的钉子都围住,然后啪一声松开手。凸包就是以橡皮圈为边界的区域。具体示意如下图1所示:

2 解决方案
2.1 蛮力法
使用蛮力法解决此问题比较简单,具体思想:对于一个n个点集合中的两个点p1和p2,当且仅当该集合中的其它点都位于穿过这两点的直线的同一边时,它们的连线就是该集合凸包边界的一部分,简言之,p1和p2就是凸包问题中最小凸多边形的顶点。对每一对点都做一遍检验之后,满足条件的线段就构成了该凸包的边界。

此时,根据上面的公式,我们只需要把每个点代入公式ax+by-c,判断公式计算结果的符号是否全部大于等于0或者小于等于0,如果是则是凸包边界上的点,否则就不是。该算法的时间效率为0(n^3)。具体代码如下:
package com.liuzhen.chapterThree;
public class ConvexHull {
//蛮力法解决凸包问题,返回点集合中凸多边形的点集合
public static Point[] getConvexPoint(Point[] A){
Point[] result = new Point[A.length];
int len = 0; //用于计算最终返回结果中是凸包中点的个数
for(int i = 0;i < A.length;i++){
for(int j = 0;j < A.length;j++){
if(j == i) //除去选中作为确定直线的第一个点
continue;
int[] judge = new int[A.length]; //存放点到直线距离所使用判断公式的结果
for(int k = 0;k < A.length;k++){
int a = A[j].getY() - A[i].getY();
int b = A[i].getX() - A[j].getX();
int c = (A[i].getX())*(A[j].getY()) - (A[i].getY())*(A[j].getX());
judge[k] = a*(A[k].getX()) + b*(A[k].getY()) - c; //根据公式计算具体判断结果
}
if(JudgeArray(judge)){ // 如果点均在直线的一边,则相应的A[i]是凸包中的点
result[len++] = A[i];
break;
}
}
}
Point[] result1 = new Point[len];
for(int m = 0;m < len;m++)
result1[m] = result[m];
return result1;
}
//判断数组中元素是否全部大于等于0或者小于等于0,如果是则返回true,否则返回false
public static boolean JudgeArray(int[] Array){
boolean judge = false;
int len1 = 0, len2 = 0;
for(int i = 0;i < Array.length;i++){
if(Array[i] >= 0)
len1++;
}
for(int j = 0;j < Array.length;j++){
if(Array[j] <= 0)
len2++;
}
if(len1 == Array.length || len2 == Array.length)
judge = true;
return judge;
}
public static void main(String[] args){
Point[] A = new Point[8];
A[0] = new Point(1,0);
A[1] = new Point(0,1);
A[2] = new Point(0,-1);
A[3] = new Point(-1,0);
A[4] = new Point(2,0);
A[5] = new Point(0,2);
A[6] = new Point(0,-2);
A[7] = new Point(-2,0);
Point[] result = getConvexPoint(A);
System.out.println("集合A中满足凸包的点集为:");
for(int i = 0;i < result.length;i++)
System.out.println("("+result[i].getX()+","+result[i].getY()+")");
}
}
上面定义的点Point类代码如下:
package com.liuzhen.chapterThree;
public class Point {
private int x;
private int y;
Point(){
x = 0;
y = 0;
}
Point(int x, int y){
this.x = x;
this.y = y;
}
public void setX(int x){
this.x = x;
}
public int getX(){
return x;
}
public void setY(int y){
this.y = y;
}
public int getY(){
return y;
}
}
运行结果:
集合A中满足凸包的点集为:
(2,0)
(0,2)
(0,-2)
(-2,0)
Java实现凸包问题的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- 算法笔记_016:凸包问题(Java)
目录 1 问题描述 2 解决方案 2.1 蛮力法 1 问题描述 给定一个平面上n个点的集合,它的凸包就是包含所有这些点的最小凸多边形,求取满足此条件的所有点. 另外,形象生动的描述: (1)我们可以把 ...
- Java基础常见英语词汇
Java基础常见英语词汇(共70个) ['ɔbdʒekt] ['ɔ:rientid]导向的 ['prəʊɡræmɪŋ]编程 OO: object ...
- hdu 1348 Wall (凸包)
Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 2202 最大三角形 (凸包)
最大三角形 Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- hdu 4946 Area of Mushroom(凸包)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946 Area of Mushroom Time Limit: 2000/1000 MS (Java/Ot ...
- hdu 1348 (凸包求周长)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others) Mem ...
- HDU 1392 凸包
Surround the Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- hdu 1348 Wall(凸包模板题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others) M ...
随机推荐
- [CodeForces 344C Rational Resistance]YY,证明
题意:给若干个阻值为1的电阻,要得到阻值为a/b的电阻最少需要多少个. 思路:令a=mb+n,则a/b=m+n/b=m+1/(b/n),令f(a,b)表示得到a/b的电阻的答案,由f(a,b)=f(b ...
- [hdu1532]最大流
裸最大流,求最大流一般步骤如下: (1)所有正向边权初始化为容量,反向边权初始化为0 (2)找增广路 (3)找到则进入(4),否则得到最大流并退出 (4) 增广路上所有边减去最小边权,相应的方向边加上 ...
- leeCode 278
你是产品经理,目前正在带领一个团队开发新的产品.不幸的是,你的产品的最新版本没有通过质量检测.由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的. 假设你有 n 个版本 [1, ...
- 使用 PyCharm 添加 Django 项目
一.前置准备(PyCharm与Python的下载,已有的跳过) 1.首先下载PyCharm 地址:http://www.jetbrains.com/pycharm/ 2.然后下载Python 地址:h ...
- jquery遍历数组、对象
1,for循环: var arr = new Array(13.5,3,4,5,6); for(var i=0;i<arr.length;i++){ arr[i] = arr[i]/2.0; } ...
- XShell 评估到期
刚刚打开XShell弹出”评估到期“,点击确定后自动打开中文官网,得购买后才能使用. 当初下载的时候没留意到会有这一天.. 手头拮据的朋友可以通过下面方法绕过: 删除XShell. 到英文官网下载页找 ...
- MySQL 数据库的基本使用
MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,而MySQL AB 公司被 Oracle 公司收购,故 MySQL 现在属于 Oracle 公司.MySQL 是一种关联数据 ...
- 14.3 Go iris
14.3 Go iris 下载 go get -u -v github.com/kataras/iris 代码示例 package main import "github.com/katar ...
- linux常用命令---文件拷贝与传输
拷贝命令 文件传输
- 02 Redis数据结构基础
一.客户端命令行参数 1.-x 从标准输入读取一个参数,等价于set k v [root@localhost etc]# echo -en 'v1'|redis-cli -a foobared -x ...