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 ...
随机推荐
- Linux登录shell和非登录(交互式shell)环境变量配置
使用Jenkins执行shell脚本的时候, 碰到command not found. 比如java mvn, 这些环境变量配置在/etc/profile 中, 但jenkins执行的时候并没有加载. ...
- mysql-kettle-superset电商可视化数据分析
1.项目概述 需求 对电商业务中的用户.商品.订单的数据进行分析,观察运营的情况 架构 业务数据库:Mysql:存储最原始的数据 ETL:Kettle 数据仓库:Mysql:存储需要进行分析处理的数据 ...
- mybatis association的使用
在上一篇文章中介绍了collection的使用以及java bean,表的结构,今天进行association使用的学习,在多对一的映射关系中,查询到多的一方顺带查询出一的一方是常见的!在此例子中,在 ...
- React实践相关
语法高亮: sublime ctrl+shift+P 安装babel ,在view-syntax-open all width current extension as...-babel-js(bab ...
- node的buffer模块
Buffer这块很早前就想留一篇笔记.前端JS处理buffer的场景其实并不多,虽然后来基于webGL与显卡通信的需求增加了二进制数组,但毕竟相对小众. Buffer的含义是,在数据传输时用内存中的一 ...
- Java基础之抽象类和接口
今天来说说抽象类和接口的实现以及它们的区别.我们知道抽象类和接口都是对具体事物的抽象,接口在实现上比抽象类更加抽象,抽象类中可以有普通方法和变量,而接口中只有抽象方法和不可变常量.但是从另一个角度看, ...
- redis集群复制和故障转移
#### 一.集群的问题- 1.当某个主节点宕机后,对应的槽位没有节点承担,整个集群处于失败状态,不可用,怎么办- 2.如何判断某个主节点是否真正的岩机?- 3.如果从某个主节点的所有从节点中选举出一 ...
- JavaScript编程入门
写在前面: 不管容易还是简单 总要尝试才知道答案 1.JavaScript初探 JavaScript:轻量级脚本语言,是可插入HTML页面的编程代码. 将JavaScript插入HTML页 ...
- DQN(Deep Q-learning)入门教程(零)之教程介绍
简介 DQN入门系列地址:https://www.cnblogs.com/xiaohuiduan/category/1770037.html 本来呢,在上一个系列数据挖掘入门系列博客中,我是准备写数据 ...
- Qt版本中国象棋开发(二)
实现功能:棋盘绘制 核心函数: void paintEvent(QPaintEvent *); //QWidget自带的虚函数,重写后使用 QPainter 类来绘制图形 QPainter paint ...