最近点对问题:给定平面上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实现例子
在前面的排序算法学习中,归并排序和快速排序就是用的分治法,分治法作为三大算法之一的,有非常多的应用例子. 分治法概念 将一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题-- ...
随机推荐
-
radio 切换内容
<!DOCTYPE html><html><head> <meta charset=utf-8 /> <title>test</tit ...
-
创业15条经验总结:温饱之后,创业公司CEO如何树“三观”?
都说创业改变命运,事实上不是,创业,时时刻刻,可能连“命”都保不住!创业公司最重要的只有“活下去”.满足了这个.才有资格谈其他.公司连饭都开不了,还谈什么其他?创业公司如果连生存问题都解决不了,高位的 ...
-
Android画图Path的使用
/** * Paint类介绍 * * Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色, * 样式等绘制信息,指定了如何绘制文本 ...
-
nodeschool.io 2
~~ BABY STEPS ~~ Write a program that accepts one or more numbers as command-line arguments and pr ...
-
看完com本质论第一章
class IUnKnown { virtual void QueryInterface(REFIID riid,IUnknown** ppv)=0; virtual void addref()=0; ...
-
wpf 如何设置滚动条在超出范围的时候才显示?(转)
VerticalScrollBarVisibility="Auto" 垂直自动显示 HorizontalScrollBarVisibility="Auto" ...
-
Cisco 绑定mac地址
在Cisco中有以下三种方案可供选择,方案1和方案2实现的功能是一样的,即在具体的交换机端口上绑定特定的主机的MAC地址(网卡硬件地址),方案3是在具体的交换机端口上同时绑定特定的主机的MAC地址(网 ...
-
[iOS]C语言技术视频-15-指针变量高级用法练习一(函数指针完成动态排序)
下载地址: 链接: http://pan.baidu.com/s/1o6MOzX4 密码: xzxn
-
reportviewer需要的3个引用
安装ReportViewer后其中会出现以下DLL. Microsoft.ReportViewer.ProcessingObjectModel.dll Micr ...
-
Windows上Boost的编译步骤
一.FQ下载Boost最新版本 官网:http://www.boost.org/ 假设解压到:D:\Applicaton\DevTools\boost\boost_1_65_1 二.使用VS编译器 c ...