Division and Recursion--find the nearest points in two dimension

#find the nearest point in two dimensions
#1 first if there are only two points, then calculate the distance directly
#2 if there are three points, get the nearest point
#3 if there are more than three points
#1 sort the point by the x value
#2 sort the points by the y value
#3 divide the points by the middle value of x
#4 get the nearest point of the two parts,get the pair whose distance is less, marked as D

import math
import unittest

def merge(list1, list2, list1_begin, list1_end, list2_begin, list2_end):
 list3 = []
 i = list1_begin
 j = list2_begin

while (i<list1_end) and (j < list2_end):
  if list1[i] < list2[j]:
   list3.append(list1[i])
   i = i+1
  else:
   list3.append(list2[j])
   j = j+1
 while(i<list1_end):
  list3.append(list1[i])
  i = i+1
 while(j<list2_end):
  list3.append(list2[j])
  j = j+1
 return list3

def mergeByX(list1, list2, list1_begin, list1_end, list2_begin, list2_end):
 list3 = []
 i = list1_begin
 j = list2_begin

while (i<list1_end) and (j < list2_end):
  if list1[i].x < list2[j].x:
   list3.append(list1[i])
   i = i+1
  else:
   list3.append(list2[j])
   j = j+1
 while(i<list1_end):
  list3.append(list1[i])
  i = i+1
 while(j<list2_end):
  list3.append(list2[j])
  j = j+1
 return list3

def array_need_to_be_merged(array, begin, end):
 list1 = []
 i = begin
 while(i<end):
  list1.append(array[i])
  i = i+1
 return list1

def mergeByY(list1, list2, list1_begin, list1_end, list2_begin, list2_end):
 list3 = []
 i = list1_begin
 j = list2_begin

while (i<list1_end) and (j < list2_end):
  if list1[i].p.y < list2[j].p.y:
   list3.append(list1[i])
   i = i+1
  else:
   list3.append(list2[j])
   j = j+1
 while(i<list1_end):
  list3.append(list1[i])
  i = i+1
 while(j<list2_end):
  list3.append(list2[j])
  j = j+1
 return list3

def doMergeByY(origin_array, step):
 i = 0
 new1 =[]
 new2 =[]
 length = len(origin_array)
 while i + 2*step < length:
  list1 = array_need_to_be_merged(origin_array, i, i+step)
  list2  = array_need_to_be_merged(origin_array, i+step, i +2*step)
  new1 += mergeByY(list1, list2, 0, step, 0, step)
  i = i + 2*step
 if i+step < length:
  list1 = array_need_to_be_merged(origin_array, i, i+step)
  list2  = array_need_to_be_merged(origin_array, i+step, length)
  new2 += mergeByY(list1, list2, 0, step, 0, length-i-step)
 else:
  while i < length:
   new2.append(origin_array[i])
   i = i+1
 sorted_array = new1+new2
 return sorted_array

def doMergeByX(origin_array, step):
 i = 0
 new1 =[]
 new2 =[]
 length = len(origin_array)
 while i + 2*step < length:
  list1 = array_need_to_be_merged(origin_array, i, i+step)
  list2  = array_need_to_be_merged(origin_array, i+step, i +2*step)
  new1 += mergeByX(list1, list2, 0, step, 0, step)
  i = i + 2*step
 if i+step < length:
  list1 = array_need_to_be_merged(origin_array, i, i+step)
  list2  = array_need_to_be_merged(origin_array, i+step, length)
  new2 += mergeByX(list1, list2, 0, step, 0, length-i-step)
 else:
  while i < length:
   new2.append(origin_array[i])
   i = i+1
 sorted_array = new1+new2
 return sorted_array

def merge_sort_by_x(origin_array):
 step =1
 length = len(origin_array)
 sorted_array = origin_array
 while step < length:
  sorted_array = doMergeByX(sorted_array, step)
  step += step
  sorted_array = doMergeByX(sorted_array,step)
 return sorted_array

def merge_sort_by_y(origin_array):
 step =1
 length = len(origin_array)
 sorted_array = origin_array
 while step < length:
  sorted_array = doMergeByY(sorted_array, step)
  step += step
  sorted_array = doMergeByY(sorted_array,step)
 return sorted_array
class point_x:
 def __init__(self, p, id):
  self.p = p
  self.id = id

class point_y:
 def __init__(self,p, index):
  self.p = p
  self.index =index
 def __str__(self):
  return "x:"+str(self.p.x)+"y:"+str(self.p.y)+"index:"+str(self.index)

class test_merge_sort(unittest.TestCase):
 def test_do_merge(self):
  p1 = point(1,2)
  p2 = point(3,4)
  p3 = point(7,5)
  p4 = point(8,6)
  list1 =[p1,p2,p3,p4]
  
  p5 = point(2,3)
  p6 = point(4,10)
  p7= point(5,9)
  p8 = point(6,7)
  list2 =[p5,p6,p7,p8]
  
  list3 = list1 + list2
  list4 = doMergeByX(list3, 4)
  list5 = [p1,p5,p2,p6,p7,p8,p3,p4]
  self.assertEqual(list4, list5)
 def test_merge_sort_by_x(self):
  p1 = point(1,2)
  p2 = point(3,4)
  p3 = point(7,5)
  p4 = point(8,6)
  p5 = point(2,3)
  p6 = point(4,10)
  p7= point(5,9)
  p8 = point(6,7)
  # p9 =point(6,7)
  list4 = merge_sort_by_x([p1,p2,p3,p4,p5,p6,p7,p8])
  list5 = [p1,p5,p2,p6,p7,p8,p3,p4]
  # print (list5.index(p3))
  self.assertEqual(list4, list5)
 # def test_merge_sort_by_y(self):
 #  p1 = point(1,2)
 #  p2 = point(3,4)
 #  p3 = point(7,5)
 #  p4 = point(8,6)
 #  p5 = point(2,3)
 #  p6 = point(4,10)
 #  p7= point(5,9)
 #  p8 = point(6,7)
 #  list4 = merge_sort_by_y([p1,p2,p3,p4,p5,p6,p7,p8])
 #  list5 = [p1,p5,p2,p3,p4,p8,p7,p6]
 #  self.assertEqual(list4, list5)
 def test_merge_sort_by_all(self):
  p1 = point(1,2)
  p2 = point(3,4)
  p3 = point(7,5)
  p4 = point(8,6)
  p5 = point(2,3)
  p6 = point(4,10)
  p7= point(5,9)
  p8 = point(6,7)
  p9 = point(6,6)
  # list4 = merge_sort_by_x([p1,p2,p3,p4,p5,p6,p7,p8])
  # list5 = [p1,p5,p2,p6,p7,p8,p3,p4]
  # origin_array = list4
  # array_y =[]
  # k=0
  # for i in origin_array:
  #  p = point_y(i,k)
  #  k=k+1
  #  array_y.append(p)
  # for x in array_y:
  #  print (x)
  # print ("begin:")
  # list6 = merge_sort_by_y(array_y)
  # for l in list6:
  #  print (l)
  # print (cal_min_distance_of_points(list6))
  print("nearest")
  print (nearest([p1,p2,p3,p4,p5,p6,p7,p8,p9]))

class point:
 def __init__(self, x, y):
  self.x = x
  self.y = y

def distance(point1, point2):
 square_x = math.pow((point1.x - point2.x), 2)
 square_y = math.pow((point1.y - point2.y), 2)
 return math.sqrt(square_y+square_x)

class test_nearest(unittest.TestCase):
 def test_distance(self):
  p1 = point(0,4)
  p2 = point(3,0)
  self.assertEqual(5.0, distance(p1,p2))
 # def test_n(self):
 #  p1 = point(1,2)
 #  p2 = point(3,4)
 #  p3 = point(7,5)
 #  d1 = distance(p1,p2)
 #  self.assertEqual(d1,find_nearest([p1,p2,p3], 0,2))

def cal_min_distance_of_points(points):
 length = len(points)
 min_d = 99000000
 i=0
 while(i< length):
  p1 = points[i].p
  j =i +1
  while(j <length):
   p2 = points[j].p
   d = distance(p1,p2)
   if (d < min_d):
    min_d = d
   j=j+1
  i = i+1
 return min_d

def find_nearest(points, point_y, left, right):
 if (right-left==1):
  return distance(points[left], points[right])
 elif(right-left==2):
  d1 = distance(points[left], points[left+1])
  d2 = distance(points[left], points[left+2])
  d3 = distance(points[left+1], points[left+2])
  if (d1<d2 and d1 < d3):
   return d1
  elif (d2<d1 and d2 <d3):
   return d2
  else:
   return d3
 else:
  m = (left+right)//2
  # print ("m")
  # print (m)
  sorted_array_y = point_y
  left_array=[]
  right_array=[]
  for i in sorted_array_y:
   if i.index <= m:
    left_array.append(i)
   else:
    right_array.append(i)
  d1 = find_nearest(points, left_array, left, m)
  d2 = find_nearest(points, right_array, m+1, right)
  min_d=d1
  if d2<d1 :
   min_d =d2
  new_array_for_cal=[]
  for i in sorted_array_y:
   if (math.fabs(i.p.x - points[m].x)<min_d):
    new_array_for_cal.append(i)
  
  d3 = cal_min_distance_of_points(new_array_for_cal) 
  if d3<min_d:
   min_d = d3
  return min_d

def nearest(points):
 origin_array = merge_sort_by_x(points)
 k=0
 array_y=[]
 for i in origin_array:
  p = point_y(i,k)
  k = k+1
  array_y.append(p)
 sorted_array_y = merge_sort_by_y(array_y)
 n = len(origin_array)
 return find_nearest(origin_array, sorted_array_y, 0, n-1)

if __name__ == "__main__":
 unittest.main()

时间: 2024-08-27 05:41:29

Division and Recursion--find the nearest points in two dimension的相关文章

计算Fisher vector和VLAD

This short tutorial shows how to compute Fisher vector and VLAD encodings with VLFeat MATLAB interface. These encoding serve a similar purposes: summarizing in a vectorial statistic a number of local feature descriptors (e.g. SIFT). Similarly to bag

聚类算法总结

最近要在spark上做一个聚类的项目,数据量和类的个数都比较大.KMeans效果尚可,但是有点慢,因而重新看了下常用的算法. kmeans attention: init centers (randomize vs kmeans++) mini-batch kmeans loops: random samples; find closest for all; update centers for each mean shift init: get centers by bandwidth loo

(转) An overview of gradient descent optimization algorithms

An overview of gradient descent optimization algorithms Table of contents: Gradient descent variantsChallenges Batch gradient descent Stochastic gradient descent Mini-batch gradient descent Gradient descent optimization algorithms Momentum Nesterov a

Fisher vector fundamentals

文章<Fisher Kernels on Visual Vocabularies for Image Categorization>中提到: Pattern classication techniques can be divided into the classes ofgenerative approaches anddiscriminative approaches. While the first class focuses onthe modeling of class-condit

机器学习算法实践——K-Means算法与图像分割

一.理论准备 1.1.图像分割 图像分割是图像处理中的一种方法,图像分割是指将一幅图像分解成若干互不相交区域的集合,其实质可以看成是一种像素的聚类过程.通常使用到的图像分割的方法可以分为: 基于边缘的技术 基于区域的技术 基于聚类算法的图像分割属于基于区域的技术. 1.2.K-Means算法 K-Means算法是基于距离相似性的聚类算法,通过比较样本之间的相似性,将形式的样本划分到同一个类别中,K-Means算法的基本过程为: 初始化常数 ,随机初始化k个聚类中心 重复计算以下过程,直到聚类中心

knn in scala

nearest neighbor algorithm -- greedy 1开始的点A(不同则答案不同) 2选择cost最小的点D 重复 3最后回到A,加总 knn in scala --intuition /** @author wyq * @version 1.0 * @date Sun Sep 22 18:45:44 EDT 2013 */ package scalation.analytics import util.control.Breaks.{breakable, break} i

An overview of gradient descent optimization algorithms

原文地址:An overview of gradient descent optimization algorithms An overview of gradient descent optimization algorithms Note: If you are looking for a review paper, this blog post is also available as an article on arXiv. Update 15.06.2017: Added deriva

LocalOutlierFactor算法回归数据预处理

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> sklearn.neighbors.LocalOutlierFactor — scikit-learn 0.20.0 documentation Home Installation Documentation Sc

wordcloud2.js

https://blogs.msdn.microsoft.com/dotnet/2019/01/10/announcing-ml-net-0-9-machine-learning-for-net/ https://marketplace.visualstudio.com/items?itemName=MLNET.07 https://dotnet.microsoft.com/learn/machinelearning-ai/ml-dotnet-get-started-tutorial https