-2

I'm facing some troubles with doing a pairwise calculation in Python.

I have two sets of nodes (e.g. suppliers and customers).

  • Set 1: SupplierCO = (Xco, Yco) for multiple suppliers
  • Set 2: Customer CO = (Xco, Yco) for multiple customers

I want to calculate the distances between a customer and all the suppliers, and save the shortest distance. This should be looped for all customers.

I realize I will have to work with two for loops, and an if function. But I don't understand how to select the coordinates from the correct points while looping.

Thanks for the responses! Some more information: - Haversine distance - Each point in set 1 has to be compared to all the points of set 2 - This is what I've so far

import urllib.parse
from openpyxl import load_workbook, Workbook
import requests
from math import radians, cos, sin, asin, sqrt

"""load datafile"""
workbook = load_workbook('Macro.xlsm')
Companysheet = workbook.get_sheet_by_name("Customersheet")
Networksheet = workbook.get_sheet_by_name("Suppliersheet")

"""search for column with latitude/longitude - customers"""
numberlatC = -1
i = 0
for col in Customersheet.iter_cols():
    if col[2].value == "Latitude" :
        numberlatC = i
    i+=1

numberlongC = -1
j = 0
for col in Customersheet.iter_cols():
    if col[2].value == "Longitude" :
        numberlongC = j
    j+=1


latC = [row[numberlatC].value for row in Companysheet.iter_rows() ]
longC = [row[numberlongC].value for row in Companysheet.iter_rows()]

# haversine formula 
    dlon = lonC - lonS 
    dlat = latC - latS 
    a = sin(dlat/2)**2 + cos(latC) * cos(latS) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    distance = c*r 
    distances.append([distance])
    return distances

customers = [latC, longC]

Thanks!

Sibren De Preter
  • 109
  • 1
  • 13
  • What are you expecting from an answer? We'd need your data to give you any concrete code. – cs95 Aug 03 '17 at 19:19
  • There's quite a bit of info missing. Euclidean, Haversine or other distance? Please show template code. It seems your idea of the approach is sound so where is it falling down? – roganjosh Aug 03 '17 at 19:23
  • May be Djikstra if he has nodes and vertices. – MishaVacic Aug 03 '17 at 19:25
  • @mishavacic ok, I missed the "shortest distance" part. You're probable right. – roganjosh Aug 03 '17 at 19:29
  • @MishaVacic But each "node" has X and Y coordinates, so probably the "nodes" are simply 2D points. – DYZ Aug 03 '17 at 19:33
  • 1
    If I google your exact question title, your question is the first result. [This is the second result](https://stackoverflow.com/questions/43650931/python-alternative-for-calculating-pairwise-distance-between-two-sets-of-2d-poin) – saintsfan342000 Aug 03 '17 at 19:42
  • Thanks all! I have updated the question to be more specific and added the code – Sibren De Preter Aug 03 '17 at 20:02

1 Answers1

0

This should give you the general idea. In the following example I've just used regular coordinates, however, you should be able to convert this to your need.

supplier = [(1,3),(2,4),(8,7),(15,14)]
customer = [(0,2),(8,8)]

def CoordinatesDistance(A, B):
    import math
    x1, x2 = A
    y1, y2 = B
    return math.sqrt(math.exp((x2-x1)+(y2-y1)))

def shortest_distance_pair(Cust, Sup):
    pairs = []
    for X in Cust:
        shortest_distance = 999999
        for Y in Sup:
            distance = CoordinatesDistance(X,Y)
            #customer_distance.append(distance)
            if distance < shortest_distance:
                shortest_distance = distance
                sdp = (X,Y)
        pairs.append(sdp)
    return pairs

print(shortest_distance_pair(customer,supplier))

print(shortest_distance_pair(customer,supplier))
[((0, 2), (8, 7)), ((8, 8), (8, 7))]

Now if you create two lists, 1. Customer coordinates, and 2. Supplier coordinates; you should be able to utilize the above.

Philip
  • 944
  • 11
  • 26
  • Thanks a lot Philip! An additional question: How do I get the data in the [(X,Y), (X,Y)] format? I can read all the Xco and all the Yco each in a list, but how do I merge them? Grts! – Sibren De Preter Aug 03 '17 at 20:48
  • That is a different question, and you should accept the answer. However, in your case, you have `customers = [latC, longC]`. To make the coordinates to a pair in the list, just add _brackets_ `customers = [(latC, longC)]`. To add more coordinates to the list: `customers.append((latC,longC))` – Philip Aug 03 '17 at 20:56
  • Thanks again! Currently I'm having a 'ValueError: too many values to unpack (expected 2)' In this pastebin my code.. I don't see where this could be caused. https://pastebin.com/itQTdrCe Thanks! – Sibren De Preter Aug 04 '17 at 22:18
  • Please add it as a new question. Then others will be able to find the answer too :) – Philip Aug 07 '17 at 09:55