Python: Getting a Distance Matrix

36 Views Asked by At

I have a problem and would like your help. I have a class (Customers) in which all customers are stored with their respective x and y coordinates. I would now like to build a distance matrix or a two dimensional list that shows the distances between customers.

I already have a working function for the distances:

# Getting Distances
def get_distance(a,b):
    d = [a.getX()- b.getX() , a.getY() - b.getY()]
    return sqrt(d[0] * d[0] + d[1] * d[1])


# Distances between Customers:
Distances = []
for i in range(0,nr_customers):
    for j in range(0, nr_customers):
        get_distance(customer[i],customer[j])
        Distances.append(get_distance(customer[i],customer[j]))

So far, of course, only one list of all distances is output. Can someone help me? Please without Numpy or Pandas, we do not allow their use.

2

There are 2 best solutions below

0
Mohsen_Fatemi On BEST ANSWER

What you are missing in your code is the distance of customer i with all other customers(including i). You are not storing them in the inner loop as a list. You need to define it in your outer loop.

# Getting Distances
def get_distance(a,b):
    return sqrt((a.getX()- b.getX())**2 + (a.getY() - b.getY())**2)


# Distances between Customers:
Distances = []
for i in range(0,nr_customers):
    distance_i = []
    for j in range(0, nr_customers):
        distance_i.append(get_distance(customer[i],customer[j]))
    Distances.append(distance_i)

Now you have the distances between all customers as a 2D list.

Although you could get the same result using scipy distance_matrix() :

# importing distance_matrix
from scipy.spatial import distance_matrix

# making a list of customers coordinates
Customer_Coordinates = [(customer[i].getX(),customer[i].getY()) for i in range(nr_customers)]

# calculating the distance matrix
d = distance_matrix(Customer_Coordinates,Customer_Coordinates)

# printing the result
print(d)
0
Daraan On

You can start directly with a matrix and save more than half of the calculations by exploiting the symmetry and that the distance of one element to itself is 0.

# Getting Distances
def get_distance(a,b):
    return sqrt((a.getX()- b.getX())**2 + (a.getY() - b.getY())**2)

# Init Matrix at 0 (this covers diagonal elements)
distance_matrix = [[0] * nr_customers] for _ in range(nr_customers)]

# Research Question for you: 
# why does matrix = [[0]*nr_customers]*nr_customers not work?

# Fill Matrix
for i in range(0,nr_customers):
    # note start at i+1 as diagonal is 0, covered by init and because symmetric
    for j in range(i+1, nr_customers): 
        dist = get_distance(customer[i],customer[j])
        distance_matrix[i,j] = distance_matrix[j,i] = dist # fill symmetric