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实现凸包问题的更多相关文章

  1. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  2. 算法笔记_016:凸包问题(Java)

    目录 1 问题描述 2 解决方案 2.1 蛮力法 1 问题描述 给定一个平面上n个点的集合,它的凸包就是包含所有这些点的最小凸多边形,求取满足此条件的所有点. 另外,形象生动的描述: (1)我们可以把 ...

  3. Java基础常见英语词汇

    Java基础常见英语词汇(共70个) ['ɔbdʒekt] ['ɔ:rientid]导向的                             ['prəʊɡræmɪŋ]编程 OO: object ...

  4. hdu 1348 Wall (凸包)

    Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. hdu 2202 最大三角形 (凸包)

    最大三角形 Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  6. hdu 4946 Area of Mushroom(凸包)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946 Area of Mushroom Time Limit: 2000/1000 MS (Java/Ot ...

  7. hdu 1348 (凸包求周长)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  8. HDU 1392 凸包

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  9. hdu 1348 Wall(凸包模板题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    M ...

随机推荐

  1. 通过PAML中的CODEML模块计算dnds的过程以及踩坑

    最近帮女朋友做毕业设计的时候用到了 PAML这个软件的codeml功能,发现网上相关的资料很少,于是把自己踩的一些坑分享一下,希望能帮到其他有相同困难的人 一.下载与安装 PAML软件下载地址 htt ...

  2. Linux,Unix,GNU 到底有什么样的渊源?

    Linux,Unix, GNU,你可能经常听到这些名字被放在一起,比如 “Linux是类Unix系统”, “Linux其实应该叫 GNU/Linux” 等等.为什么会有这些说法,这些名词的历史渊源和背 ...

  3. Mysql 常用函数(5)- substring 函数

    Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html substring 的作用 截取指定范围的字符串, ...

  4. 【转载】文件上传那些事儿,文件ajax无刷上传

    导语 正好新人导师让我看看能否把产品目前使用的FileUploader从老的组件库分离出来的,自己也查阅了相关的各种资料,对文件上传的这些事有了更进一步的了解.把这些知识点总结一下,供自己日后回顾,也 ...

  5. SpringBoot注解分析

    Spring boot 简介:是spring社区发布的一个开源项目,旨在帮助开发者更快更简单的构建项目,使用习惯优于配置,的理念让你的项目快速的跑起来,使用springboot可以不用,或者很少的配置 ...

  6. Apache自定义404

    先用命令找到httpd.conf文件在哪 find -name 'httpd.conf' 默认配置文件: vim /etc/httpd/conf/httpd.conf 然后找到项目的路径 <Di ...

  7. 数据结构----栈stack

    栈的概念与数据结构 栈(有时称为“后进先出栈”)是一个元素的有序集合,其中添加移除新元素总发生在同一端.这一端通常称为“顶部”.与顶部对应的端称为“底部”.栈的底部很重要,因为在栈中靠近底部的元素是存 ...

  8. 干货分享:如何使用Kubernetes的Ingress API

    您可以通过使用诸如Kong for Kubernetes的Ingress控制器(使用自定义资源定义并提供许多插件)来极大地扩展Ingress资源的功能. Kubernetes正在整个技术行业中得到采用 ...

  9. 处理TableVIew SectionHeader悬停问题

    1,plain类型的tableview  才会悬停  grouped类型不会悬停 2,通过改变contentInset达到部分悬停遮罩的处理,对所有的Sectionheader都有效,不可以单独处理某 ...

  10. 用 CSS Grid 布局制作一个响应式柱状图

    最新一段时间比较喜欢玩弄图表,出于好奇,我想找出比较好的用 CSS 制作图表的方案.开始学习网上开源图表库,它对我学习新的和不熟悉的前端技术很有帮助,比如这个:CSS Grid. 今天和大家分享我学到 ...