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.

Foi útil?

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top