Python “round robin”
-
05-09-2019 - |
Pergunta
múltipla Dado (x, y) pares ordenados, eu quero comparar as distâncias entre cada um deles. Então fingir que tem uma lista de pares ordenados:
pairs = [a,b,c,d,e,f]
Eu tenho uma função que leva dois pares ordenados e encontrar a distância entre eles:
def distance(a,b):
from math import sqrt as sqrt
from math import pow as pow
d1 = pow((a[0] - b[0]),2)
d2 = pow((a[1] - b[1]),2)
distance = sqrt(d1 + d2)
return distance
Como posso usar essa função para comparar cada par ordenado a todos os outros par ordenado, em última análise, encontrando os dois pares ordenados com a maior distância entre eles?
Psuedopsuedocode:
distance(a,b)
distance(a,c)
...
distance(e,f)
Qualquer ajuda seria tremendamente apreciada.
Solução
try:
from itertools import combinations
except ImportError:
def combinations(l, n):
if n != 2: raise Exception('This placeholder only good for n=2')
for i in range(len(l)):
for j in range(i+1, len(l)):
yield l[i], l[j]
coords_list = [(0,0), (3,4), (6,8)]
def distance(p1, p2):
return ( ( p2[0]-p1[0] ) ** 2 + ( p2[1]-p1[1] )**2 ) ** 0.5
largest_distance, (p1, p2) = max([
(distance(p1,p2), (p1, p2)) for (p1,p2) in combinations(coords_list, 2)
])
print largest_distance, p1, p2
Outras dicas
em python 2.6, você pode usar itertools.permutations
import itertools
perms = itertools.permutations(pairs, 2)
distances = (distance(*p) for p in perms)
ou
import itertools
combs = itertools.combinations(pairs, 2)
distances = (distance(*c) for c in combs)
Tente:
max(distance(a, b) for (i, a) in enumerate(pairs) for b in pairs[i+1:])
A identidade Evitar-comparações (por exemplo distance(x, x)
, distance(y, y)
, etc.). Ele também evita fazer comparações simétricas, uma vez distance(x, y) == distance(y, x)
.
Update: eu como solução de Evgeny para utilizar itertools
um pouco melhor, em que expressa o que você está tentando fazer de forma mais sucinta. Ambas as nossas soluções fazer a mesma coisa. (Nota: certifique-se de usar combinações , não permutações - que será muito mais lento)
ligeiramente relacionado, você não tem que calcular a distância euclidiana mesmo, há math.hypot:
In [1]: a = (1, 2)
In [2]: b = (4, 5)
In [3]: hypot(a[0]-b[0], a[1]-b[1])
Out[3]: 4.2426406871192848
Se você não se importa fazer cálculos de distância entre dois pontos que são o mesmo duas vezes, o seguinte irá encontrar a maior distância:
max( [distance(a, b) for a in pairs for b in pairs] )
Para ter a e b par em vez disso, em seguida, faça o seguinte:
import operator
max( [((a,b), distance(a, b)) for a in pairs for b in pairs], key=operator.itemgetter(1))
Você pode combinar isso com a solução da John Feminella para obter o (a, b) tupla sem fazer comparações excesso distância