Advertisement
Guest User

Untitled

a guest
Sep 1st, 2015
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.72 KB | None | 0 0
  1. rom random import randint, randrange
  2. from operator import itemgetter, attrgetter
  3.  
  4. infinity = float('inf')
  5.  
  6. # Note the use of complex numbers to represent 2D points making distance == abs(P1-P2)
  7.  
  8. def bruteForceClosestPair(point):
  9. numPoints = len(point)
  10. if numPoints < 2:
  11. return infinity, (None, None)
  12. return min( ((abs(point[i] - point[j]), (point[i], point[j]))
  13. for i in range(numPoints-1)
  14. for j in range(i+1,numPoints)),
  15. key=itemgetter(0))
  16.  
  17. def closestPair(point):
  18. xP = sorted(point, key= attrgetter('real'))
  19. yP = sorted(point, key= attrgetter('imag'))
  20. return _closestPair(xP, yP)
  21.  
  22. def _closestPair(xP, yP):
  23. numPoints = len(xP)
  24. if numPoints <= 3:
  25. return bruteForceClosestPair(xP)
  26. Pl = xP[:numPoints/2]
  27. Pr = xP[numPoints/2:]
  28. Yl, Yr = [], []
  29. xDivider = Pl[-1].real
  30. for p in yP:
  31. if p.real <= xDivider:
  32. Yl.append(p)
  33. else:
  34. Yr.append(p)
  35. dl, pairl = _closestPair(Pl, Yl)
  36. dr, pairr = _closestPair(Pr, Yr)
  37. dm, pairm = (dl, pairl) if dl < dr else (dr, pairr)
  38. # Points within dm of xDivider sorted by Y coord
  39. closeY = [p for p in yP if abs(p.real - xDivider) < dm]
  40. numCloseY = len(closeY)
  41. if numCloseY > 1:
  42. # There is a proof that you only need compare a max of 7 next points
  43. closestY = min( ((abs(closeY[i] - closeY[j]), (closeY[i], closeY[j]))
  44. for i in range(numCloseY-1)
  45. for j in range(i+1,min(i+8, numCloseY))),
  46. key=itemgetter(0))
  47. return (dm, pairm) if dm <= closestY[0] else closestY
  48. else:
  49. return dm, pairm
  50.  
  51. def times():
  52. ''' Time the different functions
  53. '''
  54. import timeit
  55.  
  56. functions = [bruteForceClosestPair, closestPair]
  57. for f in functions:
  58. print 'Time for', f.__name__, timeit.Timer(
  59. '%s(pointList)' % f.__name__,
  60. 'from closestpair import %s, pointList' % f.__name__).timeit(number=1)
  61.  
  62.  
  63.  
  64. pointList = [randint(0,1000)+1j*randint(0,1000) for i in range(2000)]
  65.  
  66. if __name__ == '__main__':
  67. pointList = [(5+9j), (9+3j), (2+0j), (8+4j), (7+4j), (9+10j), (1+9j), (8+2j), 10j, (9+6j)]
  68. print pointList
  69. print ' bruteForceClosestPair:', bruteForceClosestPair(pointList)
  70. print ' closestPair:', closestPair(pointList)
  71. for i in range(10):
  72. pointList = [randrange(11)+1j*randrange(11) for i in range(10)]
  73. print '\n', pointList
  74. print ' bruteForceClosestPair:', bruteForceClosestPair(pointList)
  75. print ' closestPair:', closestPair(pointList)
  76. print '\n'
  77. times()
  78. times()
  79. times()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement