我真是个菜鸡。又搞了一天作业。感觉python确实没有C好写算法,很多地方不严密。。。
最近对,就是n个点中找最近的一对点。
分治法,主要就是递归,把一个问题分分分分分分分,然后合合合合合合合合合。
思想很简单,但是处理了几个小时的语法,类型错误问题,还好会点调试,要不今天都不一定能找出自己写的细节错误。
废话扯完,来看看算法吧。
核心函数,有2个参数,数组的左开头和右开头。
首先判断长度,根据情况进行计算距离,向下分治(也就是递归)。
然后比较距离,将小的那个存储到一个变量。
最后就是判断中线两边点的距离,和上一个最小值进行比较。
就是这么简单。给出代码。
import random
import math
import matplotlib.pyplot as p
input = int(input('输入生成点的数量:'))
dot = [[0]*3 for i in range(input)]
mindis = 1000 * 1000
fg = p.figure()
cn = fg.add_subplot(1, 1, 1)
cn.set_xlim(0, 1000)
cn.set_ylim(0, 1000)
p.ion()
a = [1000, 1000]
b = [0, 0]
x = []
y = []
for i in range(input):
dot[i][0] = random.randrange(1000)
dot[i][1] = random.randrange(1000)
dot[i][2] = 0
dot.sort()
for i in range(input):
x.append(dot[i][0])
y.append(dot[i][1])
def distance(x, y):
return float(math.sqrt(x * x + y * y))
def dac(left, right):
global mindis, a, b
len = right - left
length = (right + left)
cn.scatter(x, y, color='b', marker='.')
if len <= 0:
dis = 9999999999999
return dis
elif len == 1:
dis = distance(dot[right][0]-dot[left][0], dot[right][1]-dot[left][1])
cn.plot([dot[left][0], dot[right][0]], [dot[left][1], dot[right][1]], color='r')
p.pause(0.1)
cn.lines.pop()
p.pause(0.1)
if dis < distance(a[0]-b[0], a[1]-b[1]):
a = [dot[right][0], dot[right][1]]
b = [dot[left][0], dot[left][1]]
return dis
else:
n = int(length / 2)
midline = (dot[n][0] + dot[n+1][0]) / 2
cn.plot([midline, midline], [0, 1000], color='b')
p.pause(0.1)
dis1 = dac(left, n)
dis2 = dac(n+1, right)
if dis1 <= dis2:
md = dis1
else:
md = dis2
if mindis > md:
mindis = md
for i in dot[left:n+1]:
if abs(i[0] - midline) <= md:
for j in dot[n+1:right+1]:
if j[0] - midline <= md:
if i[1] - md <= j[1] <= i[1] + md:
dis3 = distance(i[0]-j[0], i[1]-j[1])
if mindis > dis3:
mindis = dis3
cn.plot([i[0], j[0]], [i[1], j[1]], color='r')
p.pause(0.1)
cn.lines.pop()
p.pause(0.1)
if dis3 < distance(a[0] - b[0], a[1] - b[1]):
a = [i[0], i[1]]
b = [j[0], j[1]]
cn.lines.pop()
return mindis
list = []
c = [1000, 1000]
d = [0, 0]
for i in range(input):
for j in range(i+1, input):
list.append(distance(dot[i][0]-dot[j][0], dot[i][1]-dot[j][1]))
if distance(dot[i][0]-dot[j][0], dot[i][1]-dot[j][1]) < distance(c[0] - d[0], c[1] - d[1]):
c = [dot[i][0], dot[i][1]]
d = [dot[j][0], dot[j][1]]
list.sort()
print("检验:", list[0], c, d)
print("距离:", dac(0, input-1))
print("最近对:", a, b)
cn.plot([a[0], b[0]], [a[1], b[1]], c='b')
p.pause(5)
python函数众多,很多好用的函数都不懂。
虽然用了好几个小时,不过对python更熟悉了,也初步学会了python绘图。继续努力吧,明天能好好学逆向了。0.0