Expm 3_2 寻找最邻近的点对
【问题描述】
设p1=(x1,y1), p2=(x2,y2), … , pn=(xn,yn) 是平面上n个点构成的集合S,设计和实现找出集合S中距离最近点对的算法。
每一个格子最多只能存在一个点,三行最多存在12个顶点,因此对于上图中的第(i=27)个顶点来说,最多只需要比较第27个顶点与之后的11个顶点,对于i之后或之前的11个顶点之外的顶点j,即|i-j|>=12,i与j之间的距离一定大于d,因为i和j已经相隔了至少两行。两个顶点若相隔大于等于两行或两列,则他们之间的距离一定大于等于d
- package org.xiu68.exp.exp3;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Random;
- public class Exp3_2 {
- //设p1=(x1,y1), p2=(x2,y2), … , pn=(xn,yn)
- //是平面上n个点构成的集合S,设计和实现找出集合S中距离最近点对的算法。
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- for(int i=0;i<20;i++){
- System.out.println("***************************");
- List<Point> pointList=new ArrayList<>();
- for(int j=0;j<50;j++){
- Point p=new Point(new Random().nextInt(100),new Random().nextInt(100));
- pointList.add(p);
- }
- System.out.println(bruteforce(pointList)); //蛮力法
- System.out.println(closestPair(pointList)); //分治法
- System.out.println("****************************");
- }
- }
- //寻找最近点对
- public static double closestPair(List<Point> pointList){
- //对pointList中的点按横坐标和纵坐标进行升序排序
- List<Point> sortedListX=new ArrayList<>();
- List<Point> sortedListY=new ArrayList<>();
- //按横坐标对数组进行升序排序
- pointList.sort((Point a,Point b)->{
- if(a.getX()<b.getX())
- return -1;
- else
- return 1;
- });
- sortedListX.addAll(pointList);
- //按纵坐标对数组进行升序排序
- pointList.sort((Point a,Point b)->{
- if(a.getY()<b.getY())
- return -1;
- else
- return 1;
- });
- sortedListY.addAll(pointList);
- /* for(int i=0;i<pointList.size();i++)
- System.out.println(sortedListX.get(i));
- System.out.println("*********************");
- for(int i=0;i<pointList.size();i++)
- System.out.println(sortedListY.get(i));
- System.out.println("*********************");
- System.out.println(divide(sortedListX,sortedListY));*/
- return divide(sortedListX,sortedListY);
- }
- /*
- * 原问题的分解
- * sortedListX:横坐标升序排序的数组
- * sortedListY:纵坐标升序排序的数组
- */
- public static double divide(List<Point> sortedListX,List<Point> sortedListY){
- if(sortedListX.size()==1) //如果只有一个元素
- return Double.MAX_VALUE;
- else if(sortedListX.size()==2) //如果只有两个元素
- return dist(sortedListX.get(0),sortedListX.get(1));
- else{ //大于2个元素
- int mid=sortedListX.size()/2; //在第mid个点处把点分成左右相等的两部分
- double L=sortedListX.get(mid).getX(); //把点分成左右相等的两部分的直线的横坐标,设这条直线为L
- //L左边的点的横坐标升序排序的数组
- List<Point> sortedListXL=sortedListX.subList(0, mid);
- //L右边的点的横坐标升序排序的数组
- List<Point> sortedListXR=sortedListX.subList(mid, sortedListX.size());
- List<Point> sortedListYL=new ArrayList<>(); //L左边的点的纵坐标升序排序的数组
- List<Point> sortedListYR=new ArrayList<>(); //L右边的点的纵坐标升序排序的数组
- //求sortedListYL与sortedListYR
- for(int i=0;i<sortedListY.size();i++){
- Point p=sortedListY.get(i);
- if(sortedListY.get(i).getX()<L){
- sortedListYL.add(p);
- }else{
- sortedListYR.add(p);
- }
- }
- double dL=divide(sortedListXL,sortedListYL); //L左边两个点之间的最短距离
- double dR=divide(sortedListXR,sortedListYR); //L右边两个点之间的最短距离
- //比较L左边最短距离、L右边最短距离以及跨越L的顶点对之间的最短距离
- return conquer(sortedListY,L,Math.min(dL, dR));
- }//else
- }
- //子问题解的合并
- public static double conquer(List<Point> sortedListY,double L,double d){
- //求在L-d以及L+d之间的顶点(2d-strip)
- List<Point> inside2DList=new ArrayList<>();
- for(int i=0;i<sortedListY.size();i++){
- Point p=sortedListY.get(i);
- if(p.getX()>L-d || p.getX()<L+d){
- inside2DList.add(p);
- }
- }
- //求2d-strip之间顶点对的最短距离、与L左边和右边的最短距离比较,最小者为最终结果
- double minDistance=d;
- for(int i=0;i<inside2DList.size()-1;i++){
- //i只需与i之后的11个顶点比较,i与大于11个顶点之后的顶点的距离一定大于等于d
- for(int j=i+1;j<=i+11 && j<inside2DList.size();j++){
- double temp=dist(inside2DList.get(i),inside2DList.get(j));
- if(temp<minDistance)
- minDistance=temp;
- }
- }
- return minDistance;
- }
- //计算两点之间的距离
- public static double dist(Point a,Point b){
- return Math.sqrt(Math.pow(a.getX()-b.getX(), 2)+Math.pow(a.getY()-b.getY(), 2));
- }
- //蛮力法
- public static double bruteforce(List<Point> pointList){
- double minDistance=Double.MAX_VALUE;
- //依次比较每个顶点对
- for(int i=0;i<pointList.size();i++){
- for(int j=i+1;j<pointList.size();j++){
- double temp=dist(pointList.get(i),pointList.get(j));
- if(temp<minDistance)
- minDistance=temp;
- }
- }
- return minDistance;
- }
- }
- class Point{
- private double x; //横坐标
- private double y; //纵坐标
- public Point(int x,int y){
- this.x=x;
- this.y=y;
- }
- public double getX() {
- return x;
- }
- public void setX(double x) {
- this.x = x;
- }
- public double getY() {
- return y;
- }
- public void setY(double y) {
- this.y = y;
- }
- public String toString(){
- return x+","+y;
- }
- }
Expm 3_2 寻找最邻近的点对的更多相关文章
- 机器学习 第4篇:sklearn 最邻近算法概述
sklearn.neighbors 提供了针对无监督和受监督的基于邻居的学习方法的功能.监督的基于最邻近的机器学习算法是值:对带标签的数据的分类和对连续数据的预测(回归). 无监督的最近算法是许多其他 ...
- 机器学习 第5篇:knn回归
基于最邻近算法的分类,本质上是对离散的数据标签进行预测,实际上,最邻近算法也可以用于对连续的数据标签进行预测,这种方法叫做基于最邻近数据的回归,预测的值(即数据的标签)是连续值,通过计算数据点最临近数 ...
- [Elasticsearch] 邻近匹配 (三) - 性能,关联单词查询以及Shingles
提高性能 短语和邻近度查询比简单的match查询在性能上更昂贵.match查询仅仅是查看词条是否存在于倒排索引(Inverted Index)中,而match_phrase查询则须要计算和比較多个可能 ...
- [Elasticsearch] 邻近匹配 (一) - 短语匹配以及slop參数
本文翻译自Elasticsearch官方指南的Proximity Matching一章. 邻近匹配(Proximity Matching) 使用了TF/IDF的标准全文搜索将文档,或者至少文档中的每一 ...
- [LeetCode] Find the Celebrity 寻找名人
Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist o ...
- [LeetCode] Find Minimum in Rotated Sorted Array II 寻找旋转有序数组的最小值之二
Follow up for "Find Minimum in Rotated Sorted Array":What if duplicates are allowed? Would ...
- [LeetCode] Find Minimum in Rotated Sorted Array 寻找旋转有序数组的最小值
Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...
- C语言 · 寻找数组中的最大值
问题描述 对于给定整数数组a[],寻找其中最大值,并返回下标. 输入格式 整数数组a[],数组元素个数小于1等于100.输出数据分作两行:第一行只有一个数,表示数组元素个数:第二行为数组的各个元素. ...
- 【跟着子迟品 underscore】如何优雅地写一个『在数组中寻找指定元素』的方法
Why underscore (觉得这部分眼熟的可以直接跳到下一段了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. ...
随机推荐
- 原生js操作option
<script type="text/javascript"> // 1.动态创建select function createSelect() { var mySele ...
- 通过纯真IP地址实现根据用户地址显示信息
为了实现中关村在线商品报价中通过用户的地理位置信息显示相应的报价. 示例地址:http://detail.zol.com.cn/lens/index224693.shtml 现把我做的使用asp.ne ...
- springboot配置多环境
https://www.cnblogs.com/jason0529/p/6567373.html Spring的profiles机制,是应对多环境下面的一个解决方案,比较常见的是开发和测试环境的配 ...
- 地址空间格局随机化ASLR
Address space layout randomization(ASLR)是一种参与保护缓冲区溢出问题的一个计算机安全技术.是为了防止攻击者在内存中能够可靠地对跳转到特定利用函数.ASLR包括随 ...
- DTLS协议中client/server的认证过程和密钥协商过程
我的总结:DTLS的握手就是协商出一个对称加密的秘钥(每个客户端的秘钥都会不一样),之后的通信就要这个秘钥进行加密通信.协商的过程要么使用非对称加密算法进行签名校验身份,要么通过客户端和服务器各自存对 ...
- my read travel
s 江苏省5A级旅游景区 ▪ 无锡中视股份三国水浒景区 ( 无锡) ▪ 中山陵景区 ( 南京) ▪ 南京夫子庙 ( 南京) ▪ 周庄古镇游览区 ( 苏州) ▪ 中华恐龙园 ( 常州) ▪ 金坛市 ( ...
- 学习Git笔记
一.名词解释 1.仓库(Repository) 仓库用来存放项目代码,每个项目对应一个仓库,多个开源项目则有多个仓库. 2.收藏(Star) 收藏项目,方便下次查看 3.复制克隆项目(Fork) 该f ...
- Neural Networks and Deep Learning 课程笔记(第三周)浅层神经网络(Shallow neural networks)
3.1 神经网络概述(Neural Network Overview ) (神经网络中,我们要反复计算a和z,最终得到最后的loss function) 3.2 神经网络的表示(Neural Netw ...
- JMS学习(七)-ActiveMQ消息的持久存储方式之KahaDB存储
一,介绍 自ActiveMQ5.4以来,KahaDB成为了ActiveMQ默认的持久化存储方式.相比于原来的AMQ存储方式,官方宣称KahaDB使用了更少的文件描述符,并且提供了更快的存储恢复机制. ...
- scapy的安装
我是安装了sulley,这里安装了pcapy的模块. https://github.com/zlorb/scapy ----按照此链接的步骤安装 但是在安装pycrypto模块出现了错误. 这里通 ...