`
128kj
  • 浏览: 582937 次
  • 来自: ...
社区版块
存档分类
最新评论

学习凸包(二):分治法求解

阅读更多
接上文:学习凸包(一):暴力算法求解http://128kj.iteye.com/blog/1748442





import java.util.*;   
class Line {//线   
 Point p1, p2;   
 Line(Point p1, Point p2) {   
  this.p1 = p1;   
  this.p2 = p2;   
 }   

  public double getLength() {
	double dx = Math.abs(p1.x - p2.x);
	double dy = Math.abs(p1.y - p2.y);
	return Math.sqrt(dx * dx + dy * dy);
  }

}   
  
class Point{//点   
  double x;   
  double y;   
  
  public Point(double x,double y){
     this.x=x;
     this.y=y;
  }
}   


/*
*	分治法求凸包
*/
class QuickTuBao  {
  List<Point> pts = null;//给出的点集
  List<Line> lines = new ArrayList<Line>();//点集pts的凸包
	
  public void setPointList(List<Point> pts) {
      this.pts = pts;
  }

  public QuickTuBao(List<Point> pts){
      this.pts=pts;
  }

  //求凸包,结果存入lines中
  public List<Line> eval() {
      lines.clear();
      if (pts == null || pts.isEmpty()) { return lines; }
        List<Point> ptsLeft = new ArrayList<Point>();//左凸包中的点
          List<Point> ptsRight = new ArrayList<Point>();//右凸包中的点
		
        //按x坐标对pts排序
         Collections.sort(pts, new Comparator<Point>() {
             public int compare(Point p1, Point p2) {
              if(p1.x-p2.x>0) return 1;
              if(p1.x-p2.x<0) return -1;
              return 0;
             } 
			
		});  
         
            Point p1 = pts.get(0);//最左边的点
            Point p2 = pts.get(pts.size()-1);//最右边的点,用直线p1p2将原凸包分成两个小凸包
            Point p3 = null;
            double area = 0;
            for (int i = 1; i < pts.size(); i++) {//穷举所有的点,
              p3 = pts.get(i);
              area = getArea(p1, p2, p3);//求此三点所成三角形的有向面积
                if (area > 0) {		
                 ptsLeft.add(p3);//p3属于左
                } else if (area < 0) {
                  ptsRight.add(p3);//p3属于右
                }
              }
              d(p1, p2, ptsLeft);//分别求解
              d(p2, p1, ptsRight);
              return lines;
   }

   private void d(Point p1, Point p2, List<Point> s) {
     //s集合为空
     if (s.isEmpty()) {
       lines.add(new Line(p1, p2));
       return;
     }
     //s集合不为空,寻找Pmax
     double area = 0;
     double maxArea = 0;
     Point pMax = null;
     for (int i = 0; i < s.size(); i++) {
      area = getArea(p1, p2, s.get(i));//最大面积对应的点就是Pmax
      if (area > maxArea) {
        pMax = s.get(i);
        maxArea = area;
       }
      }
      //找出位于(p1, pMax)直线左边的点集s1
      //找出位于(pMax, p2)直线左边的点集s2
       List<Point> s1 = new ArrayList<Point>();
       List<Point> s2 = new ArrayList<Point>();
       Point p3 = null;
       for (int i = 0; i < s.size(); i++) {
         p3 = s.get(i);
         if (getArea(p1, pMax, p3) > 0) {
            s1.add(p3);
         } else if (getArea(pMax, p2, p3) > 0) {
            s2.add(p3);
         } 
        }
       //递归
       d(p1, pMax, s1);
      d(pMax, p2, s2);	
    }
	// 三角形的面积等于返回值绝对值的二分之一
	// 当且仅当点p3位于直线(p1, p2)左侧时,表达式的符号为正
	private double getArea(Point p1, Point p2, Point p3) {
           return p1.x * p2.y + p3.x * p1.y + p2.x * p3.y -
             p3.x * p2.y - p2.x * p1.y - p1.x * p3.y;
	}
}


代码来自:http://blog.163.com/maxupeng@yeah/

未完,待续.....
  • 大小: 16.5 KB
  • 大小: 28.8 KB
0
0
分享到:
评论

相关推荐

    高级算法设计实验1分治算法:求解凸包问题

    求解凸包问题:输入是平面上 n 个点的集合 Q,凸包问题是要输出一个 Q 的 凸包。其中,Q 的凸包是一个凸多边形 P,Q 中的点或者在 P 上或者在 P 中。 实现基于枚举方法的凸包求解算法...实现基于分治思想的凸包求解算法

    分治法求解凸包问题

    利用分治法求解凸包问题!c语言 #include #define PPmax 30 #define random(x) (rand()%x) typedef struct node{ float x,y; }Point; Point DingDian[PPmax];//用于存放凸边形的顶点 int DingDnum=0; typedef ...

    凸包分治法

    分治法求解凸包问题一个简单的程序实验报告可以用

    分治法凸包问题

    分治法求解凸包问题,能够运行的出来,已运行调试过

    算法实验凸包枚举、Graham-Scan、分治三种解决方法

    哈工大算法实验一,凸包...3.实现基于分治思想的凸包求解算法 4.界面图,可以用鼠标随便点,然后用这些点求出凸包并在界面上画出凸包源代码和实验报告!均为自己所做,正确运行。报告中还有用Excel表分析了算法的性能

    基于分治法和分支限界法的大规模TSP算法 (2012年)

    该算法利用聚类和凸包技术将大规模问题逐层进行有效划分,直到适合分支限界法求解的最佳规模;然后用分支限界法求出每个子问题和每层子问题间的最优解,合并而得到整个问题的解。比较实验表明:该算法在求解质量、稳定性...

    蛮力法姊妹篇 | Python分治法解决凸包问题并用matplotlib实现可视化以及与蛮力法的对比

    之前写了一篇Python蛮力法解决凸包问题并用matplotlib实现可视化,最后也给出了同样是在1000个点的情况下蛮力法和分治法的差距有多大(蛮力法1154秒,分治法0.125秒…) 先解释一下为什么吧: 因为蛮力法的重点在于...

    2015300005_黄晓阳_计算几何算法与应用大作业1

    1.凸包问题概述 2.分治法的基本原理 3.用分治法求解凸包问题策略

    算法导论(part1)

    2.3.2 分治法分析 第3章 函数的增长 3.1 渐近记号 3.2 标准记号和常用函数 第4章 递归式 4.1 代换法 .4.2 递归树方法 4.3 主方法 *4.4 主定理的证明 4.4.1 取正合幂时的证明 4.4.2 上取整...

    挑战程序设计竞赛(第2版)

    4.6 划分、解决、合并:分治法 4.6.1 数列上的分治法 4.6.2 树上的分治法 4.6.3 平面上的分治法 4.7 华丽地处理字符串 4.7.1 字符串上的动态规划算法 4.7.2 字符串匹配 4.7.3 后缀数组 4.8 一起来挑战GCJ的题目(3)...

    算法设计与分析 王红梅

    3 .6 几何问题中的蛮力法 3 .6 .1 最近对问题 3 .6 .2 凸包问题 3 .7 实验项目— — —串匹配问题 阅读材料— — —蚁群算法 习题 3 第 4 章 分治法 4 .1 概述 4 .1 .1 分治法的设计思想 4 .1 .2 分治法的求解过程 ...

    leetcode算法题主函数如何写-HangDian-OJ:杭电OJ刷题进度跟踪算法(c\c++\python)

    &gt;排序问题的分治法 B1066 简单分治法 B1067 根下2的近似解 (给定一个定义在[L, R]上的单调函数f(x), 求方程f(x)=0的根) B1068 快排(数列接近有序) 此时最坏的时间复杂度为O(n^2), 原因是主元没有把当前区间划分为两...

    算法导论中文版

     2.3.1 分治法  2.3.2 分析分治算法  思考题  本章注记 第3章 函数的增长  3.1 渐近记号  3.2 标准记号与常用函数  思考题  本章注记 第4章 分治策略  4.1 最大子数组问题  4.2 矩阵乘法的...

    算法导论(part2)

    2.3.2 分治法分析 第3章 函数的增长 3.1 渐近记号 3.2 标准记号和常用函数 第4章 递归式 4.1 代换法 .4.2 递归树方法 4.3 主方法 *4.4 主定理的证明 4.4.1 取正合幂时的证明 4.4.2 上取整...

    算法引论:一种创造性方法.[美]Udi Manber(带详细书签).pdf

    本书的特色有二,旨在提高读者的问题求解能力,使读者能够理解算法设计的过程和思想:一是强调算法设计的创造性过程,注重算法设计背后的创造性思想,而不拘泥于某个具体算法的详细讨论;二是将算法设计类比于定理...

    kuangbin acm模板超级好用

    3.2.2 二维 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 3.3 树链剖分 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 3.3.1 点权 . . ....

Global site tag (gtag.js) - Google Analytics