《算法》BEYOND 部分程序 part 3

? 书中第六章部分程序,加上自己补充的代码,包括 Graham 扫描生成凸包,计算最远点对

● Graham 扫描生成凸包

 1 package package01;
 2
 3 import java.util.Arrays;
 4 import edu.princeton.cs.algs4.StdIn;
 5 import edu.princeton.cs.algs4.StdOut;
 6 import edu.princeton.cs.algs4.Point2D;
 7 import edu.princeton.cs.algs4.Stack;
 8
 9 public class class01
10 {
11     private Stack<Point2D> hull = new Stack<Point2D>();
12
13     public class01(Point2D[] points)
14     {
15         if (points == null || points.length == 0)
16             throw new IllegalArgumentException("argument is null");
17         int n = points.length;
18         Point2D[] a = new Point2D[n];
19         for (int i = 0; i < n; i++)
20             a[i] = points[i];
21
22         Arrays.sort(a);                             // Y 坐标升序排序,等值的按 X 坐标升序排序,保证 a[0] 为最下最左,a[1] 为
23         Arrays.sort(a, 1, n, a[0].polarOrder());    // 以 a[0] 为原点,幅角升序排序
24         hull.push(a[0]);                            // 第一个点
25         int k1;                                     // 找到下一个相异点
26         for (k1 = 1; k1 < n; k1++)
27         {
28             if (!a[0].equals(a[k1]))
29                 break;
30         }
31         if (k1 == n)
32             return;
33         int k2;                                     // 找到下一个非共线点
34         for (k2 = k1 + 1; k2 < n; k2++)
35         {
36             if (Point2D.ccw(a[0], a[k1], a[k2]) != 0)
37                 break;
38         }
39         hull.push(a[k2 - 1]);                       // a[k2-1] 是与 a[0],a[k1] 共线的最后一个点(也可以先压 a[k1] 然后跳过 a[k2-1])
40         for (int i = k2; i < n; i++)
41         {
42             Point2D top = hull.pop();
43             for (; Point2D.ccw(hull.peek(), top, a[i]) <= 0; top = hull.pop()); // 倒数第 2 点、倒数第 1 点和当前点计算三角形面积,逆时针方向为正
44                                                                                 // 吐栈吐到这 3 点的面积为正为止,压入倒数第 2 点当前点
45             hull.push(top);
46             hull.push(a[i]);
47         }
48         assert isConvex();
49     }
50
51     public Iterable<Point2D> hull()                 // 得到凸包的迭代器
52     {
53         Stack<Point2D> s = new Stack<Point2D>();
54         for (Point2D p : hull)
55             s.push(p);
56         return s;
57     }
58
59     private boolean isConvex()                      // 检查凸性
60     {
61         int n = hull.size();
62         if (n <= 2) return true;
63
64         Point2D[] points = new Point2D[n];
65         int k = 0;
66         for (Point2D p : hull())
67             points[k++] = p;
68
69         for (int i = 0; i < n; i++)
70         {
71             if (Point2D.ccw(points[i], points[(i + 1) % n], points[(i + 2) % n]) <= 0)
72                 return false;
73         }
74         return true;
75     }
76
77     public static void main(String[] args)
78     {
79         int n = StdIn.readInt();
80         Point2D[] points = new Point2D[n];
81         for (int i = 0; i < n; i++)
82         {
83             int x = StdIn.readInt(), y = StdIn.readInt();
84             points[i] = new Point2D(x, y);
85         }
86         class01 graham = new class01(points);
87         for (Point2D p : graham.hull())
88             StdOut.println(p);
89     }
90 }

● 计算最远点对

 1 package package01;
 2
 3 import edu.princeton.cs.algs4.StdIn;
 4 import edu.princeton.cs.algs4.StdOut;
 5 import edu.princeton.cs.algs4.Point2D;
 6 import edu.princeton.cs.algs4.GrahamScan;
 7
 8 public class class01
 9 {
10     private Point2D best1, best2;
11     private double bestDistanceSquared = Double.NEGATIVE_INFINITY;  // 当前最远点对距离的平方
12
13     public class01(Point2D[] points)
14     {
15         if (points == null || points.length <= 1)
16             throw new IllegalArgumentException("constructor argument is null");
17
18         GrahamScan graham = new GrahamScan(points);
19
20         int m = 0;// 凸包点数
21         for (Point2D p : graham.hull())
22             m++;
23         Point2D[] hull = new Point2D[m + 1];                        // 凸包顶点放入 a[1] ~ a[m]
24         m = 1;
25         for (Point2D p : graham.hull())
26             hull[m++] = p;
27         m--;                                                        // m 等于凸包顶点数
28
29         if (m == 1) // 所有点都相同
30             return;
31         if (m == 2) // 所有点共线
32         {
33             best1 = hull[1];
34             best2 = hull[2];
35             bestDistanceSquared = best1.distanceSquaredTo(best2);
36             return;
37         }
38
39         int k = 2;
40         for (; Point2D.area2(hull[m], hull[1], hull[k + 1]) > Point2D.area2(hull[m], hull[1], hull[k]); k++);   // a[k] 是距离直线 a[1]a[m] 最远的点
41
42         int j = k;
43         for (int i = 1; i <= k && j <= m; i++)                      // j 搜索后半部分,i 搜索前半部分
44         {
45             update(hull[i], hull[j]);                               // i 挪动一位,检查 a[i] 和 a[j] 距离是否更大
46             for (j++; (j <= m) && Point2D.area2(hull[i], hull[i + 1], hull[j]) > Point2D.area2(hull[i], hull[i + 1], hull[j - 1]); j++)
47                                                                     // j 挪动保持 a[j] 远离直线 a[i]a[i+1]
48                 update(hull[i], hull[j]);
49         }
50     }
51
52     private void update(Point2D x, Point2D y)
53     {
54         double distanceSquared = x.distanceSquaredTo(y);
55         if (distanceSquared > bestDistanceSquared)
56         {
57             best1 = x;
58             best2 = y;
59             bestDistanceSquared = distanceSquared;
60         }
61     }
62
63     public Point2D either()
64     {
65         return best1;
66     }
67
68     public Point2D other()
69     {
70         return best2;
71     }
72
73     public double distance()
74     {
75         return Math.sqrt(bestDistanceSquared);
76     }
77
78     public static void main(String[] args)
79     {
80         int n = StdIn.readInt();
81         Point2D[] points = new Point2D[n];
82         for (int i = 0; i < n; i++)
83         {
84             int x = StdIn.readInt(), y = StdIn.readInt();
85             points[i] = new Point2D(x, y);
86         }
87         class01 farthest = new class01(points);
88         StdOut.println(farthest.distance() + " from " + farthest.either() + " to " + farthest.other());
89     }
90 }

原文地址:https://www.cnblogs.com/cuancuancuanhao/p/10115990.html

时间: 2024-11-13 03:59:50

《算法》BEYOND 部分程序 part 3的相关文章

在Hadoop上运行基于RMM中文分词算法的MapReduce程序

原文:http://xiaoxia.org/2011/12/18/map-reduce-program-of-rmm-word-count-on-hadoop/ 在Hadoop上运行基于RMM中文分词算法的MapReduce程序 23条回复 我知道这个文章标题很“学术”化,很俗,让人看起来是一篇很牛B或者很装逼的论文!其实不然,只是一份普通的实验报告,同时本文也不对RMM中文分词算法进行研究.这个实验报告是我做高性能计算课程的实验里提交的.所以,下面的内容是从我的实验报告里摘录出来的,当作是我学

[转]各种排序算法及其java程序实现

原文:http://blog.csdn.net/t12x3456/article/details/7430700 各种排序算法:冒择路(入)兮(稀)快归堆,桶式排序,基数排序 冒泡排序,选择排序,插入排序,稀尔排序,快速排序,归并排序,堆排序,桶式排序,基数排序 一.冒泡排序(BubbleSort)1. 基本思想: 两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止.2. 排序过程: 设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的

FCM算法的matlab程序(初步)

FCM算法的matlab程序 在https://www.cnblogs.com/kailugaji/p/9648430.html文章中已经介绍了FCM算法,现在用matlab程序实现它. 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1.采用iris数据库 iris_data.txt 5.1 3.5 1.4 0.2 4.9 3 1.4 0.2 4.7 3.2 1.3 0.2 4.6 3.1 1.5 0.2 5 3.6 1.4 0.2 5.4 3.

GMM算法的matlab程序(初步)

GMM算法的matlab程序 在https://www.cnblogs.com/kailugaji/p/9648508.html文章中已经介绍了GMM算法,现在用matlab程序实现它. 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1.采用iris数据库 iris_data.txt 5.1 3.5 1.4 0.2 4.9 3 1.4 0.2 4.7 3.2 1.3 0.2 4.6 3.1 1.5 0.2 5 3.6 1.4 0.2 5.4 3.

K-means算法的matlab程序(初步)

K-means算法的matlab程序 在https://www.cnblogs.com/kailugaji/p/9648369.html 文章中已经介绍了K-means算法,现在用matlab程序实现它. 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1.采用iris数据库 iris_data.txt 5.1 3.5 1.4 0.2 4.9 3 1.4 0.2 4.7 3.2 1.3 0.2 4.6 3.1 1.5 0.2 5 3.6 1.4 0

FCM算法的matlab程序2

FCM算法的matlab程序2 在"FCM算法的matlab程序"这篇文章中已经用matlab程序对iris数据库进行实现,并求解准确度.下面的程序是另一种方法,是最常用的方法:先初始化聚类中心,在进行迭代(此方法由于循环较多,时间复杂度相对较高,但更严谨.就时间性而言,推荐使用"FCM算法的matlab程序"这个程序). 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1.采用iris数据库 iris_data.tx

李航老师的《统计学习方法》第二章算法的matlab程序

参考了http://blog.sina.com.cn/s/blog_bceeae150102v11v.html#post % 感知机学习算法的原始形式,算法2.1参考李航<统计学习方法>书中第二章的算法P29 close allclear allclcX=[3,3;4,3;1,1];Y=[1,1,-1];%训练数据集及标记learnRate=1;%学习率Omega=zeros(1,size(X,2))b=0 %% ω和b的初值 i=1;k=0;while 1 if Y(i)*(sum(Omeg

由一个简单算法想到的程序员素养问题

题记:五月从帝都回到武汉,旅游半个月后开始找新工作,六月选择了一家华中地区为数不多的移动互联网公司入职至今,略有感触——比较帝都码农与武汉码农的平均水平,就跟两个城市的经济发展水平差异一样大,不是说武汉这边没有优秀的程序员(我也算半个嘛),而是说平均水平确实不如其他一线城市.想想也正常,巨头公司都扎堆北上广深,以极具竞争力的薪酬福利和巨头光环吸引着广大程序员,反观武汉的互联网发展尚处在初级阶段,无论从公司规模.名气还是最实际的薪酬福利方面均不如一线城市,自然无法吸引广大程序员咯.本人在新公司待了

KMP算法-C语言程序实现

原理参考ACM算法训练教程一书 ////////////////////////////////////////////////// /*KMP算法*/ #include<stdio.h> #include<string.h> #include<iostream> using namespace std; void getNext(char a[],int next[]){ int i,j; next[1] = 0; j = 0; i = 2; int m = strl

算法_冒泡程序

这里的第一个算法,没什么可以说的,一定是从最经典的冒泡算法开始,会列出python版和c版 冒泡算法很简单,就是像冒泡一样,把小的,也可以理解成轻的,从下面浮出来 比如有个list = [3,2,5,4,1],先用3和2比,2轻,2浮上去,3沉下去,3再和5比,3比较轻,位置不变,5和4比,4浮上来,5和1比,1浮上来 第一次比完,得到[2,3,4,1,5],再进行第二次,第三次,直到把没有可以浮的了,就结束,通常这个算法的版本是嵌套循环,就是for for,好像掉进这个圈出不来了,其实不用全部