用分治法解决最近点对问题:python实现
最近点对问题:给定平面上n个点,找其中的一对点,使得在n个点的所有点对中,该点对的距离最小。需要说明的是理论上最近点对并不止一对,但是无论是寻找全部还是仅寻找其中之一,其原理没有区别,仅需略作改造即可。本文提供的算法仅寻找其中一对。
解决最近点对问题最简单的方法就是穷举法,这样时间复杂度是平方级,可以说是最坏的策略。如果使用分治法,其时间复杂度就是线性对数级,这样大大提高了效率。
首先用分治法解决该问题的基本思路可以参考 http://blog.csdn.net/lishuhuakai/article/details/9133961 ,说的很详细,但大致思路就是先根据x轴把所有点平分,然后分别在每一部分寻找最近点对,最后通过比较选一个最小的。当然其中最核心的地方是跨域求距离,原文写的很清楚,在此就不再赘述了。
以下是代码:
from math import sqrt def nearest_dot(s):
len = s.__len__()
left = s[0:len/2]
right = s[len/2:]
mid_x = (left[-1][0]+right[0][0])/2.0 if left.__len__() > 2: lmin = nearest_dot(left) #左侧部分最近点对
else: lmin = left
if right.__len__() > 2: rmin = nearest_dot(right) #右侧部分最近点对
else: rmin = right if lmin.__len__() >1: dis_l = get_distance(lmin)
else: dis_l = float("inf")
if rmin.__len__() >1: dis_2 = get_distance(rmin)
else: dis_2 = float("inf") d = min(dis_l, dis_2) #最近点对距离 mid_min=[]
for i in left:
if mid_x-i[0]<=d : #如果左侧部分与中间线的距离<=d
for j in right:
if abs(i[0]-j[0])<=d and abs(i[1]-j[1])<=d: #如果右侧部分点在i点的(d,2d)之间
if get_distance((i,j))<=d: mid_min.append([i,j]) #ij两点的间距若小于d则加入队列
if mid_min:
dic=[]
for i in mid_min:
dic.append({get_distance(i):i})
dic.sort(key=lambda x: x.keys())
return (dic[0].values())[0]
elif dis_l>dis_2:
return rmin
else:
return lmin # 求点对的距离
def get_distance(min):
return sqrt((min[0][0]-min[1][0])**2 + (min[0][1]-min[1][1])**2) def divide_conquer(s):
s.sort(cmp = lambda x,y : cmp(x[0], y[0]))
nearest_dots = nearest_dot(s)
print nearest_dots
测试一下,比如说要找这些点中最近的一对s=[(0,1),(3,2),(4,3),(5,1),(1,2),(2,1),(6,2),(7,2),(8,3),(4,5),(9,0),(6,4)]
运行一下divide_conquer(s),最终打印出[(6, 2), (7, 2)],Bingo
用分治法解决最近点对问题:python实现的更多相关文章
- Leetcode 240 Search a 2D Matrix II (二分法和分治法解决有序二维数组查找)
1.问题描写叙述 写一个高效的算法.从一个m×n的整数矩阵中查找出给定的值,矩阵具有例如以下特点: 每一行从左到右递增. 每一列从上到下递增. 2. 方法与思路 2.1 二分查找法 依据矩阵的特征非常 ...
- hdu 1007 Quoit Design(分治法求最近点对)
大致题意:给N个点,求最近点对的距离 d :输出:r = d/2. // Time 2093 ms; Memory 1812 K #include<iostream> #include&l ...
- 分治法解决合并排序(c++和Java源代码)
Java源代码 public class Mergesort1 { public static void merge(int[]a,int low,int mid,int high){//对两组已经排 ...
- p1257 平面上最接近点对---(分治法)
首先就是一维最接近点的情况... #include<iostream> #include<cstdio> #include<cstring> #include< ...
- 分治法求一个N个元素数组的逆序数
背景 逆序数:也就是说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时, ...
- 分治法(一)(zt)
这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它 ...
- python 实现分治法的几个例子
分治法所能解决的问题一般具有以下几个特征: 1) 该问题的规模缩小到一定的程度就可以容易地解决 2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质. 3) 利用该问题分解出的子 ...
- C语言实现快速排序法(分治法)
title: 快速排序法(quick sort) tags: 分治法(divide and conquer method) grammar_cjkRuby: true --- 算法原理 分治法的基本思 ...
- 分治法及其python实现例子
在前面的排序算法学习中,归并排序和快速排序就是用的分治法,分治法作为三大算法之一的,有非常多的应用例子. 分治法概念 将一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题-- ...
随机推荐
- Sublime text3插件安装方法
一.安装sublime text3插件的方法: 1.Ctrl+~键,调出console,将下面代码复制到底部命令行,回车: import urllib.request,os; pf = 'Packag ...
- Javascript 类继承
Js继承 JavaScript并不是真正面向对象的语言,是基于对象的,没有类的概念. 要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现 /** 声明一个基础父类 ...
- Spring MVC 项目搭建 -6- spring security 使用自定义Filter实现验证扩展资源验证,使用数据库进行配置
Spring MVC 项目搭建 -6- spring security使用自定义Filter实现验证扩展url验证,使用数据库进行配置 实现的主要流程 1.创建一个Filter 继承 Abstract ...
- SQL Server 文件结构 与 全局变量,函数
SQL Server 文件结构与全局变量 数据库和表 文件类型 主数据文件 .mdf 次要数据文件 .ndf 日志文件 .ldf 系统数据库 master 数据库 记录所有的登陆账户和系统配置设置 记 ...
- 网络编程学习笔记(二)基于TCP的Socket编程
1.Socket:英文意思插座.两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket. 2.Socket通常用来实现client-server(客户端 ...
- Watson Explorer Analytical Components 1
Introduction: IBM Watson Explorer Analytical Components(AC) which is part of the IBM Watson Explorer ...
- 函数的上下文就是函数里面的this是谁
规律1:函数用圆括号调用,函数的上下文是window对象 比如小题目: function fun(){ var a = 888; alert(this.a); //实际上访问的是window.a } ...
- Apache的作用及意义
Apache服务器只是作为一个转接url的服务器,根据客户端发送的url,转接到对应的运行服务器(比如:tomcat自带的服务器)中进行相应的运行操作. 使用Apache的好处,可以隐藏掉运行服务的u ...
- 修改WCF的默认序列化格式
需求: 要用WCF生成 Restful风格的接口,返回 JOSN格式: { "AInfo": { ", "Description": ...
- Java系列 – 用Java8新特性进行Java开发太爽了(续)
本人博客文章网址:https://www.peretang.com/using-java8s-new-features-to-coding-is-awesome-2/ 前言 上周, 我们谈论了关于Ja ...