0

how to calculate the distance between multiple points in a list using a loop.

def create_list(x_range,y_range, locations):
  generated_list = []
  for x in range(locations):
    x_range = random.randint(-300,300)
    y_range = random.randint(-300,300)
    generated_list.append([x_range, y_range])
  return generated_list

above creates a random list and I need to calculate the total distance for all points returning back to the beginning using this code:

def calculate_distance(starting_x, starting_y, destination_x, destination_y):
    distance = math.hypot(destination_x - starting_x, destination_y - starting_y)  # calculates Euclidean distance (straight-line) distance between two points
    return distance

here I need to calculate the distance between all points using a loop with the function above, how would I use a loop to calculate the distance between all points

Marzan
  • 1
  • 1
  • 4
  • What does mean between all point ? Like from `[p1, p2, p3]` compute `d(p1, p2), d(p1, p3),d(p2, p3) ` ? – azro Apr 09 '20 at 12:10
  • so the first function will generate random coordinates like [[5,3],[6,9],[7,2]] and I need to calculate the distance between these points using the second function. I know I need to iterate through the list but how would I do that to calculate the total distance? – Marzan Apr 09 '20 at 12:13
  • Please answer the quesiton in my previous comment, because you reused the tricky expression 'between all points" – azro Apr 09 '20 at 12:14
  • oh sorry couldn't see your full comment for some reason. so I have a(x1,y2), b(x3,y4), c(x5,y6) as points on a graph for example. I want to calculate the Euclidean distance. so I need to iterate through so it does this: (x1 - x3) + (y2 - y4) which would be the distance between point a and point b. Then assign this distance to a variable and store it. I then want tot calculate the distance between point b and point c and after that the distance between point c to point a and add all these values which will equate to thre total distance between all points. I hope this is a bit more clearer? – Marzan Apr 09 '20 at 12:21
  • You could have just said *yes* to the question :D, i'm answering right now – azro Apr 09 '20 at 12:22
  • oh yeah I could've just done that, just wanted to explain it in more depth so it would be easier to understand and thank you for your help – Marzan Apr 09 '20 at 12:24

3 Answers3

1

Scipy can generate the matrix of distances without using a loop. https://stackoverflow.com/a/19475995

Since the matrix is symmetrical around 0 we can divide the sum by two to get the one-way distances between points.

from scipy.spatial.distance import cdist
values = create_list(300, 300, 3)
distances = cdist(values, values)  
print distances.sum() / 2
Chris Lill
  • 11
  • 2
0

From a list of pairs (x, y) you may

  • use itertools.permutations to get the permutations inside this list. Here is an example with 3 points, you got 6 permutations by specifying a length of 2

    values  = [(2, 1), (0, 3), (3, 2)]
    
    perm = [((2, 1), (0, 3)),   ((2, 1), (3, 2)),   ((0, 3), (2, 1)), 
            ((0, 3), (3, 2)),   ((3, 2), (2, 1)),   ((3, 2), (0, 3))]
    
  • call your calculate_distance with the points

    p1 = (1,2)
    p2 = (2,3)
    dist = calculate_distance(*p1, *p2) #or calculate_distance(p1[0], p1[1], p2[0], p2[1])
    

Use all of this

values = create_list(300, 300, 3)
for p1, p2 in permutations(values, r=2):
    dist = calculate_distance(*p1, *p2)
    print(p1, p2, dist)

To sum them all add a value to do total+=dist in the loop, or use sum that accepts an iterable and shorten in

values = create_list(300, 300, 3)
total = sum(calculate_distance(*p1, *p2) for p1, p2 in permutations(values, r=2))

Using loops

Sum consecutive points only

# Way 1 : d(a,b) + d(b,c) + d(c,d) + d(d,e) + d(e,a)
total = calculate_distance(*values[-1], *values[0])  # between  last and first
for i in range(len(values) - 1):
    total += calculate_distance(*values[i], *values[i + 1])
print(total)

Sum all combinations of points

# Way 2: d(a,b) + d(a,c) + d(a,d) + d(a,e) + d(b,c) + d(b,d) + d(b,e) + d(c,d) + d(c,e) + d(d,e)
total = 0
for p1 in values:
    for p2 in values:
        if p1 != p2:
            total += calculate_distance(*p1, *p2)
print(total)
azro
  • 53,056
  • 7
  • 34
  • 70
  • but my `create_list` function is creating random generated list and so I don't know the points – Marzan Apr 09 '20 at 12:31
  • @Marzan Look at the end, the permutation method return 2 points by iteration, so here you have the points, the points values are random only that – azro Apr 09 '20 at 12:34
  • Permutations are a lot more complicated than this problem. The objective (to me) is to learn how to add together numbers in a loop. I think it is just the distance from a to b + b to c + c to d + d to e + e to a (if there are 5 points). – Marichyasana Apr 09 '20 at 12:40
  • is there a way of doing this by using a for loop in range so then I can iterate through in the calculate_distance function? – Marzan Apr 09 '20 at 12:41
  • @Marichyasana yes that's what I want to do but how would I use a for loop in range for `calculate_distance` function so it calculates the distance from a to b and stores it in a variable and then calculates the next distance from b to c and adds that distance to the distance we saved already in a variable – Marzan Apr 09 '20 at 12:44
  • @Marzan We're going back to the initial problem about which distances to compute, look at https://pastebin.com/R6WGMnHC is it way 1 or way 2 you want ? – azro Apr 09 '20 at 12:48
  • I want to do is, I have a list of points [5,2] , [6,3], [8,9]. I want to use the `calculate_distance` function to be able to take the 4 parameters and calculate the distance between them. so first it would take [5,2] and [6,3] as its parameters and calculate the distance and I want it to store that distance in a variable. then I want it to iterate through the list so it then takes in [6,3] and [8,9] and calculates the distance and adds that distance to the variable we already have which stored the distance for the previous calculation. need calculate_distance to iterate it using for loop @azro – Marzan Apr 09 '20 at 12:56
  • @Marzan Look the edit and try to get it working the way you expect, I stop here, sorry but you keep repeating excatly the same speech – azro Apr 09 '20 at 12:58
  • would I add that in `calculate_distance` function? – Marzan Apr 09 '20 at 12:59
  • azro@ calculate_distance has 4 arguments – Marichyasana Apr 09 '20 at 13:17
  • azro@ No disrespect intended, I figured someone with your points would do it right. I'll look it up, may be useful to me in the future. – Marichyasana Apr 09 '20 at 14:20
  • @Marzan look the "Sum consecutive points only" part, the total variable is initialize with distance between last and first point, then the look does the consecutives points – azro Apr 09 '20 at 20:54
  • if you wouldn't mine me asking you a question, how would you recommend someone get better at coding. any books or website where you can go and improve? I know the more you practise the better you get but what would you advise be for someone like me to get better? @azro – Marzan Apr 09 '20 at 21:00
  • @Marzan Just google "python tuto" and try some, then try stuff, then challenge you and try stuff, I have no other advice as for myself I did not follow a tutorial, I had needs and look for every piece of code I needed, and doing that lot to know the language – azro Apr 09 '20 at 21:02
0
import math

def calculate_distance(x1, y1, x2, y2):
    distance = math.hypot(x2 - x1, y2 - y1)
    return distance


def total_dist(ml):  # ml is a list of pairs of x,y points
    n = len(ml)
    total = 0.0
    for i in range (n):
        x1 = ml[i][0]
        y1 = ml[i][1]
        if i < n-1:
            x2 = ml[i+1][0]
            y2 = ml[i+1][1]
        else:
            x2 = ml[0][0]
            y2 = ml[0][1]
        dist = calculate_distance(x1,y1,x2,y2)
        total += dist
    return total

# main program
copy_list = [[110, -260], [284, -152], [-197, -167], [-253, 295], [-89, 26], [-165, 43], [-84, 148], [-188, 38], [201, 191], [232, 251]]
print total_dist(copy_list)
Marichyasana
  • 2,966
  • 1
  • 19
  • 20
  • how would i pass my list through this because i am generating a random list from the function `create_list` and this can have multiple x, y pairs. if you look at my list function, i have assigned it to `copy_list`, how would i pass this through your loop in a separate function which will then call the `calculate_distance` function? – Marzan Apr 09 '20 at 14:48
  • I don't see "copy_list", only the two functions. The code I provide is the main program that uses the two functions; first calls "create_list" to get a list of x,y pairs. The rest of the code uses "calculate_distance" and adds them together.If you have some other function to create the list of pairs use that instead of "mylist = create_list(0,0,n)" I can try to make a complete program if you want. – Marichyasana Apr 09 '20 at 17:23