Python 用蛮力最接近的一对点

Python 用蛮力最接近的一对点,python,Python,我不知道我的代码出了什么问题。我生成了100个随机点,我想找到这些点中最接近的一对,但结果是错误的 #Closest pair from math import sqrt from random import randint arr1=[] dist=0 p1=[] p2=[] min1=1000 for i in range(0, 100): arr1.append([randint(0,100),randint(0,100)]) print(arr1) print("\n")

我不知道我的代码出了什么问题。我生成了100个随机点,我想找到这些点中最接近的一对,但结果是错误的

#Closest pair
from math import sqrt
from random import randint

arr1=[]

dist=0
p1=[]
p2=[]
min1=1000
for i in range(0, 100):
    arr1.append([randint(0,100),randint(0,100)])

print(arr1)
print("\n")

def dist(a,b):
    x=pow((a[0]-b[0]),2)
    y=pow((a[1]-b[1]),2)
    return sqrt(x+y)

for i in range(0, len(arr1)):
    for j in range(i+1, len(arr1)):
    dis=dist(arr1[i],arr1[j])
    if(dis<min1):
        min1=dis
        p1=arr1[i]
        p2=arr1[j+1]

print(p1,"",p2,min1)
#print (sorted(arr1))
#最近的一对
从数学导入sqrt
从随机导入randint
arr1=[]
距离=0
p1=[]
p2=[]
min1=1000
对于范围(0,100)内的i:
arr1.追加([randint(0100),randint(0100)])
打印(arr1)
打印(“\n”)
def区(a、b):
x=pow((a[0]-b[0]),2)
y=pow((a[1]-b[1]),2)
返回sqrt(x+y)
对于范围(0,len(arr1))中的i:
对于范围(i+1,len(arr1))内的j:
dis=dist(arr1[i],arr1[j])

如果(DIS

OKEY)假设(1, 5)和(5, 1)是正确的点。但是当你从I+1循环到100时,你添加了ARR1[j+1 ],我猜这是错误的,当J=100时,你得到最接近的点,那么你将最终得到ARR1[101 ]。

它只适用于第一个点,对于列表中的所有其他点,您只需检查(i+1到n)中的其余点,而不是所有点。(最接近的点也可能在0到i中)

您应该在for循环中使用enumerate,现在您正在检查i对以及数组中出现在i对之后的所有对,那么在i对之前的对呢? 另外,您需要将满足距离条件的第一对和第二对保存为i对和j对,为什么要保存[j+1]对

试试这个,我认为它应该有用:

from math import sqrt
from random import randint
arr1=[]

dist=0
p1=[]
p2=[]
min1=1000
for i in range(0, 100):
  arr1.append([randint(0,100),randint(0,100)])

print(arr1)
print("\n")


def dist(a,b):
  x=pow((a[0]-b[0]),2)
  y=pow((a[1]-b[1]),2)
  return sqrt(x+y)


 for i,x in enumerate (arr1):
   for j,y in enumerate (arr1):
    if (x != y):
    dis=dist(arr1[i],arr1[j])
    if(dis<min1):
      min1=dis
      p1=arr1[i]
      p2=arr1[j]


print(p1,"",p2,min1)
print (sorted(arr1))
从数学导入sqrt
从随机导入randint
arr1=[]
距离=0
p1=[]
p2=[]
min1=1000
对于范围(0,100)内的i:
arr1.追加([randint(0100),randint(0100)])
打印(arr1)
打印(“\n”)
def区(a、b):
x=pow((a[0]-b[0]),2)
y=pow((a[1]-b[1]),2)
返回sqrt(x+y)
对于枚举中的i,x(arr1):
对于枚举中的j,y(arr1):
如果(x!=y):
dis=dist(arr1[i],arr1[j])

如果(dis,如İhsan Cemilçek所述,代码的主要问题是您有
p2=arr1[j+1]
,应该是
p2=arr1[j]

但是,您可以做一些事情来提高代码的效率

对于非负的
d1
d2
,如果
sqrt(d1)
,那么
d1
,我们可以只测试平方距离,当我们找到最小值时,我们只需要进行一次昂贵的平方根计算

Python有一个高效的
min
函数,因此无需手动查找最小值。通常,
min
对传递给它的值进行简单比较,但也可以为它提供一个键函数,它将使用该键函数进行比较

您可以使用标准的
itertools
模块中的
combines
功能,通过单个循环从您的积分列表中生成项目对。这不会节省很多时间,但比使用双循环更干净

此外,在开发生成随机值的代码时,最好为随机数生成器提供种子值。这使得测试和调试代码更加容易,因为它可以使结果重现

在下面的代码中,我增加了坐标的范围,因为有100个坐标在0到100范围内的点,生成重复点的可能性很高。如果不想重复点,您可能希望使用集合而不是列表

from math import sqrt
from random import seed, randint
from itertools import combinations

seed(17)

high = 1000
numpoints = 100

points = [(randint(0, high), randint(0, high)) for _ in range(numpoints)]
points.sort()
print(points, '\n')

def dist(t):
    a, b = t
    x = a[0] - b[0]
    y = a[1] - b[1]
    return x*x + y*y

t = min(combinations(points, 2), key=dist)
a, b = t
print('{} {}: {}'.format(a, b, sqrt(dist(t))))
输出

[(9, 51), (18, 443), (19, 478), (21, 635), (27, 254), (50, 165), (52, 918), (55, 746), (70, 316), (95, 707), (112, 939), (113, 929), (126, 903), (132, 256), (143, 832), (145, 698), (154, 692), (187, 200), (197, 765), (201, 154), (203, 317), (217, 51), (244, 119), (257, 983), (258, 880), (264, 76), (273, 65), (279, 343), (296, 178), (325, 655), (326, 174), (338, 552), (340, 96), (363, 51), (368, 59), (381, 585), (383, 593), (393, 834), (411, 140), (412, 496), (419, 83), (485, 648), (491, 76), (513, 821), (519, 962), (534, 424), (539, 980), (545, 572), (549, 312), (555, 87), (564, 63), (566, 923), (568, 545), (570, 218), (577, 537), (592, 801), (618, 848), (655, 614), (673, 413), (674, 314), (677, 284), (702, 141), (702, 215), (721, 553), (732, 654), (749, 974), (762, 279), (764, 429), (766, 732), (770, 756), (771, 356), (784, 722), (789, 319), (792, 5), (805, 282), (810, 896), (821, 978), (824, 911), (826, 310), (830, 323), (831, 418), (832, 518), (836, 400), (859, 256), (862, 996), (866, 700), (879, 485), (888, 415), (903, 722), (930, 588), (931, 496), (938, 356), (942, 323), (942, 344), (948, 429), (967, 741), (980, 254), (982, 488), (982, 604), (983, 374)] 

(381, 585) (383, 593): 8.246211251235321

事实并非如此。如果你这样做,你只会检查每一对两次。例如,点0检查从1到99的每一点的距离。一旦你到达点1,它已经检查了点0的距离,因此它不需要再次检查,当你通过点时也会发生同样的事情谢谢你。ac根据这段代码,如果我想生成10个点并找到最接近的一对,结果之一是:[[29,98],[34,50],[11,59],[87,73],[99,15],[8,1],[93,26],[53100],[11,97],[1,32][99,15][93,26]12.529964086141668是正确的。非常感谢您。此代码执行两倍于所需的测试:对于给定的
i
j
无需同时测试
dist(arr1[i],arr1[j])
dist(arr1[j],arr1[i])
,但这正是您的代码所要做的。我已经修复了代码的缩进,但以后在这里发布代码时请确保它是正确的。正确的缩进在Python中至关重要。