用分治法解决最近点对问题: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实现例子
在前面的排序算法学习中,归并排序和快速排序就是用的分治法,分治法作为三大算法之一的,有非常多的应用例子. 分治法概念 将一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题-- ...
随机推荐
- 【Android Developers Training】 76. 用Wi-Fi创建P2P连接
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- java底层学习---1
JRE: Java Runtime EnvironmentJDK:Java Development Kit JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库.是使用java语 ...
- SQLyog简介
一.软件简介 SQLyog 是一个快速而简洁的图形化管理MYSQL数据库的工具,它能够在任何地点有效地管理你的数据库.SQLyog是业界著名的Webyog公司出品的一款简洁高效.功能强大的图形化MyS ...
- Win7使用USB口连接H3C交换机的Console口
使用Console线的一端连接交换机的Console口,另一端连接电脑的USB口. 使用驱动精灵安装USB转串口驱动,我电脑上面提示安装的是: Prolific PL2303 USB转串口驱动1.16 ...
- jsp登陆页面验证码在火狐浏览器不能刷新问题处理方案
jsp登陆页面在火狐浏览器验证码不能刷新问题处理方案: <img src="YzmServlet" onClick="this.src='YzmServlet?ti ...
- usaco training 4.2.2 The Perfect Stall 最佳牛栏 题解
The Perfect Stall题解 Hal Burch Farmer John completed his new barn just last week, complete with all t ...
- HDU 1051 Wooden Sticks 贪心||DP
Wooden Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- POJ 2251 三维BFS(基础题)
Dungeon Master Description You are trapped in a 3D dungeon and need to find the quickest way out! Th ...
- PHP运算符知识点
表达式 几乎所写的任何东西都是一个表达式,简单却最精确的定义一个表达式的方式就是"任何有值的东西". 算术运算符 Php中常用的有:+.-.*./.%(取模,得到余数) 左+ - ...
- 计算BMI
用一个小程序计算BMI 代码如下: package Day06; public class BMI { private String name; private int age; private do ...