Home > Blockchain >  Determine closest location using euclidian distance in Python
Determine closest location using euclidian distance in Python

Time:11-24

So I'm struggling to find the closest Euclidean distance of two coordinates from data in a dictionary.
First, I have figured out how to compute the distance between two Cartesian coordinates (x,y) using the following:

from math import sqrt
def distance(loc1_coordinates, loc2_coordinates):
    point1x, point1y = loc1_coordinates
    point2x, point2y = loc2_coordinates
    Distance = sqrt((point1x-point2x)**2   (point1y-point2y)**2)  
    return "The distance between this two points is", str(round(Distance, 14)) " units"

print(distance([0,0],[3,4])) # distance should be 5.0

How to create a new function based on my earlier function so that I get the following as a result?

cities = {'A':[5,21], 'B':[43,76], 'C':[56,19], 'D':[21,37], 'E':[76,23], 'F':[45,56], 'G':[23,13]}
print(closest_destination('A', cities)) # should be 'G'

Update: I am trying to find the smallest distance in the list of calculations of the inputted City: eg: comparing A->B, A->C, A->D, ... and pick the one who has the closest distance

CodePudding user response:

First, change your function to return a numeric value instead of a string (in general you should have functions return values that will let you do other useful things with them in your code, rather than turning them into English-language representations):

from math import sqrt
def distance(loc1_coordinates, loc2_coordinates):
    point1x, point1y = loc1_coordinates
    point2x, point2y = loc2_coordinates
    return sqrt((point1x-point2x)**2   (point1y-point2y)**2)  

One of the useful things you can do with this function is to use it as a key in the min function to find the minimum distance:

def closest_destination(city: str, cities: dict) -> str:
    """Given a city in a {city: coord} dict, return closest other city."""
    other_cities = {k: v for k, v in cities.items() if k != city}
    return min(other_cities, key=lambda o: distance(cities[o], cities[city]))

and then:

cities = {'A':[5,21], 'B':[43,76], 'C':[56,19], 'D':[21,37], 'E':[76,23], 'F':[45,56], 'G':[23,13]}
print(closest_destination('A', cities)) # prints 'G'

CodePudding user response:

A single pass approach is to use the key parameter of min:

def closest_destination(source, locations):
    source_location = locations[source]
    return min(locations, key=lambda loc: (loc == source, distance(source_location, locations[loc])))


cities = {'A': [5, 21], 'B': [43, 76], 'C': [56, 19], 'D': [21, 37], 'E': [76, 23], 'F': [45, 56], 'G': [23, 13]}
print(closest_destination('A', cities))  # should be 'G'

Output

G

The idea of the function:

lambda loc: (loc == source, distance(source_location, locations[loc]))

to map each city key to a tuple where the first value is 1 if it is equal to the source, therefore it will always come last. Then you break the ties by distance.

  • Related