编程作业三

作业链接:Pattern Recognition & Checklist

我的代码:BruteCollinearPoints.java & FastCollinearPoints.java & Point.java

问题简介

计算机视觉涉及分析视觉图像中的模式并重建产生它们的现实世界对象。该过程通常分为两个阶段:特征检测和模式识别。特征检测涉及选择图像的重要特征;模式识别涉及发现特征中的模式。我们将研究一个涉及点和线段的特别简单的模式识别问题。这种模式识别出现在许多其他应用中,例如统计数据分析。

The problem. Given a set of n distinct points in the plane, find every(maximal) line segment that connects a subset of 4 or more of the points.

给定一些点,要求找到所有至少包含四个点的线段。

任务摘要

Point data type. Create an immutable data type Point that represents a point in the plane by implementing the following API:

public class Point implements Comparable<Point> {
public Point(int x, int y) // constructs the point (x, y) public void draw() // draws this point
public void drawTo(Point that) // draws the line segment from this point to that point
public String toString() // string representation public int compareTo(Point that) // compare two points by y-coordinates, breaking ties by x-coordinates
public double slopeTo(Point that) // the slope between this point and that point
public Comparator<Point> slopeOrder() // compare two points by slopes they make with this point
}

实现表示点的数据类型,要求完成后三个方法,详细参见:specification

Brute force. Write a program BruteCollinearPoints.java that examines 4 points at a time and checks whether they all lie on the same line segment, returning all such line segments. To check whether the 4 points p, q, r, and s are collinear, check whether the three slopes between p and q, between p and r, and between p and s are all equal.

public class BruteCollinearPoints {
public BruteCollinearPoints(Point[] points) // finds all line segments containing 4 points
public int numberOfSegments() // the number of line segments
public LineSegment[] segments() // the line segments
}

除了暴力检测每四个点是否共线(\(n^{4}\)),还有更快的做法,对点 P:

  • 把 P 当做原点。

  • 其它点按和点 P 的斜率(slope)排序。

  • 检查是否有三个点(或者更多)有同样的斜率。如果有,那这些点和点 P 就构成目标线段。

对其它的点,重复上述过程,就能找到所有目标线段,因为排序把斜率一样的点聚在一起。而这算法更快是因为瓶颈操作是排序,排序是 nlgn,最后是 \(n^{2}lgn\),也比 \(n^{4}\) 好得多。

Write a program FastCollinearPoints.java that implements this algorithm.

public class FastCollinearPoints {
public FastCollinearPoints(Point[] points) // finds all line segments containing 4 or more points
public int numberOfSegments() // the number of line segments
public LineSegment[] segments() // the line segments
}

问题分析

仍然按照 Checklist 里建议的编程步骤,先实现 Point.java。下载 Point.java,完成要求实现的方法。实际上,specification 里说得挺详细的,没什么问题,大概主要是让我们熟悉下可比较接口和比较器。

  • The compareTo() method should compare points by their y-coordinates, breaking ties by their x-coordinates. Formally, the invoking point (x0, y0) is less than the argument point (x1, y1) if and only if either y0 < y1 or if y0 = y1 and x0 < x1.

  • The slopeTo() method should return the slope between the invoking point (x0, y0) and the argument point (x1, y1), which is given by the formula (y1 − y0) / (x1 − x0). Treat the slope of a horizontal line segment as positive zero; treat the slope of a vertical line segment as positive infinity; treat the slope of a degenerate line segment (between a point and itself) as negative infinity.

  • The slopeOrder() method should return a comparator that compares its two argument points by the slopes they make with the invoking point (x0, y0). Formally, the point (x1, y1) is less than the point (x2, y2) if and only if the slope (y1 − y0) / (x1 − x0) is less than the slope (y2 − y0) / (x2 − x0). Treat horizontal, vertical, and degenerate line segments as in the slopeTo() method.

  • Do not override the equals() or hashCode() methods.

slopeTo() 方法两个点连线水平时返回正零,Checklist 里也有解释。

What does it mean for slopeTo() to return positive zero?

Java (and the IEEE 754 floating-point standard) define two representations of zero: negative zero and positive zero.

double a = 1.0;
double x = (a - a) / a; // positive zero ( 0.0)
double y = (a - a) / -a; // negative zero (-0.0)

Note that while (x == y) is guaranteed to be true, Arrays.sort() treats negative zero as strictly less than positive zero. Thus, to make the specification precise, we require you to return positive zero for horizontal line segments. Unless your program casts to the wrapper type Double (either explicitly or via autoboxing), you probably will not notice any difference in behavior; but, if your program does cast to the wrapper type and fails only on (some) horizontal line segments, this may be the cause.

接着实现 BruteCollinearPoints.java ,逻辑比较简单,还给了很多提示,也没问题。

To form a line segment, you need to know its endpoints. One approach is to form a line segment only if the 4 points are in ascending order (say, relative to the natural order), in which case, the endpoints are the first and last points.

Hint: don't waste time micro-optimizing the brute-force solution. Though, there are two easy opportunities. First, you can iterate through all combinations of 4 points (N choose 4) instead of all 4 tuples (N^4), saving a factor of 4! = 24. Second, you don't need to consider whether 4 points are collinear if you already know that the first 3 are not collinear; this can save you a factor of N on typical inputs.

把点排下序,线段的起始点自然就是遍历的头尾,甚至也教我们怎么排序。

How do I sort a subarray in Java?

Arrays.sort(a, lo, hi) sorts the subarray from a[lo] to a[hi-1] according to the natural order of a[]. You can use a Comparator as the fourth argument to sort according to an alternate order.

于是,最后的 FastCollinearPoints.java 相对复杂些。我是用了两个排序,一开始和暴力算法一样先按自然顺序排,就是先比 y 再比 x 那种,另一个是遍历点的时候按和该点的斜率排。斜率一样计数的就 ++,不小于三个再看这点的自然顺序是不是最小,是最小才将其和自然顺序最大的组成线段存起来。通过这种方法,获得线段的起始点,避免重复加入线段。

测试结果

Programming Assignment 3: Pattern Recognition的更多相关文章

  1. Algorithms : Programming Assignment 3: Pattern Recognition

    Programming Assignment 3: Pattern Recognition 1.题目重述 原题目:Programming Assignment 3: Pattern Recogniti ...

  2. Coursera Algorithms Programming Assignment 3: Pattern Recognition (100分)

    题目原文详见http://coursera.cs.princeton.edu/algs4/assignments/collinear.html 程序的主要目的是寻找n个points中的line seg ...

  3. Pattern Recognition and Machine Learning-02-1.0-Introduction

    Introduction The problem of searching for patterns in data is a fundamental one and has a long and s ...

  4. Pattern Recognition And Machine Learning读书会前言

    读书会成立属于偶然,一次群里无聊到极点,有人说Pattern Recognition And Machine Learning这本书不错,加之有好友之前推荐过,便发了封群邮件组织这个读书会,采用轮流讲 ...

  5. Pattern Recognition and Machine Learning (preface translation)

    前言 鉴于机器学习产生自计算机科学,模式识别却起源于工程学.然而,这些活动能被看做同一个领域的两个方面,并且他们同时在这过去的十年间经历了本质上的发展.特别是,当图像模型已经作为一个用来描述和应用概率 ...

  6. 获取Avrix上Computer Vision and Pattern Recognition的论文,进一步进行统计分析。

    此文主要记录我在18年寒假期间,收集Avrix论文的总结 寒假生活题外   在寒假期间,爸妈每天让我每天跟着他们6点起床,一起吃早点收拾,每天7点也就都收拾差不多.   早晨的时光是人最清醒的时刻,而 ...

  7. 课程一(Neural Networks and Deep Learning),第三周(Shallow neural networks)—— 3.Programming Assignment : Planar data classification with a hidden layer

    Planar data classification with a hidden layer Welcome to the second programming exercise of the dee ...

  8. Algorithms: Design and Analysis, Part 1 - Programming Assignment #1

    自我总结: 1.编程的思维不够,虽然分析有哪些需要的函数,但是不能比较好的汇总整合 2.写代码能力,容易挫败感,经常有bug,很烦心,耐心不够好 题目: In this programming ass ...

  9. talib 中文文档(十二):Pattern Recognition Functions K线模式识别,形态识别

    Pattern Recognition Functions K线模式识别,形态识别 CDL2CROWS - Two Crows 函数名:CDL2CROWS 名称:Two Crows 两只乌鸦 简介:三 ...

随机推荐

  1. Spring ResponseEntity

    简单记录下 ResponseEntity 的使用方式 @RequestMapping(value="/demo1" ) public ResponseEntity demo1(){ ...

  2. vue 项目其他规范

    列表 vuex数据管理 * 数据模块化:vuex数据管理-数据模块化 数据适配:vuex数据管理-数据适配 数据共享:vuex数据管理-数据共享 路由优化 keep-alive组件设置 保留滚动位置 ...

  3. Java转义emoji等特殊符号

    写在前面 网上找了很多转emoji等方法,大多有两种方法 更改数据库编码格式为utf8mb4 过滤字符串中的emoji 都不是很优雅 更改数据库编码,势必影响其他数据库 过滤emoj效率比较低 处理E ...

  4. Spring-mvc登录方法及JSP的拦截

    添加登录拦截器:LoginInterceptor import javax.servlet.http.HttpServletRequest; import javax.servlet.http.Htt ...

  5. 搜索过滤Tip : title,site(搜标题和搜网站)

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~拿老东家作例子了.........

  6. AWK工具的用法

    基本格式 awk '{commands}' filename 或者 stdin | awk '{commands}' 以下,均简写为awk '{commands}'的形式 commands的用法 co ...

  7. eclipse .properties插件

    资源文件 即 .properties 文件是常用于国际化: eclipse默认的 .properties 文件编辑器有几个问题: 编码问题 多种语言同步问题 下面介绍2种eclipse的 .prope ...

  8. Java基础——GUI编程(三)

    接着前两篇学习笔记,这篇主要介绍布局管理器和对话框两部分内容. 一.布局管理器 先拿一个小例子来引出话题,就按照我们随意的添加两个按钮来说,会产生什么样的效果,看执行结果. import java.a ...

  9. 【RabbitMQ】1、RabbitMQ的几种典型使用场景

    RabbitMQ主页:https://www.rabbitmq.com/ AMQP AMQP协议是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现.它主要包括以下组件: 1.Serve ...

  10. gulp前端自动化环境搭建详解

    1.安装 nodejs Grunt和所有grunt插件都是基于nodejs来运行的, https://nodejs.org/ 安装完成之后在终端 node -v 查看安装版本  npm -v 查看np ...