python动态演示分治法解决最近对问题
我真是个菜鸡。又搞了一天作业。感觉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