OR Tools – Creating Distance Matrix
Question:
I am using Google OR Tools for solving the capacitated vehicle routing problem with pickups and deliveries. I am importing distance matrix from MSSQL database and struggling to formulate the distance matrix.
Following are the tasks to be delivered :
taskid SiteID
CFR CFRC21126412A8612122
CFRORFC2207-002969 CFRC21126412A8612122
CFRORFC2207-003940 CFRC21085782A8615004
DC VISIT CFRP30036
We also have times and distance in database, hence formulated the matrix as such:
Just struggling to see how I can output this to distance and time matrix as per required by VRP . Following is my drafted code :
with sqlConn.cursor() as cursor:
cursor.execute('EXEC [dbo].[get_Active_Tasks_Origin_Destination]')
result = cursor.fetchall()
dd=[]
for i in range(len(tasks)):
row=[]
for j in range(len(tasks)): ##what to loop here
print("dat i j={}".format(result[i][3])) ##need to get Average KM or Time here
row.append(result[i][4])
dd.append(row)
print(type(dd[0][1]))
Following is my result[i]
result[i]
('CFR', 'CFRORFC2207-003940', 'CFRC21126412A8612122', 'CFRC21085782A8615004', 0.297, 0.0399742)
Answers:
Just struggling to see how I can output this to distance and time matrix as per required by VRP .
When using OR-tools to solve VRP, you don’t necessarily need a distance or time matrix. You can provide a callback to calculate the distance between two nodes. This allows you the freedom to represent the distance in any way you want.
Here are some options:
-
A 2D list. Let’s call it mat
. Then you get the distance from node i
to node j
by doing mat[i][j]
. The limitation is that i
and j
must be integers.
-
Nested dictionaries. This uses the exact same syntax as a 2D list, but now i
and j
can be whatever type you want (as long as it is hashable). So for example, you can use strings as the indexes.
-
Use the dataframe directly. Both of the other options require that you transform your dataframe into another data structure. You can use the dataframe directly and implement logic to get the distance from it.
Source: https://developers.google.com/optimization/routing/vrp
Following is my eventual solution:
-
Store the results in Panda’s DataFrame
with sqlConn.cursor() as cursor:
cursor.execute(f'EXEC [dbo].[get_Active_Tasks_Origin_Destination_v2] ?', str(tenantid_num))
df = pd.DataFrame.from_records(cursor.fetchall(), columns = [desc[0] for desc in cursor.description])
cursor.close()
-
Use the pivot_table method to create the matrix
data['time_matrix'] = df.pivot_table(index='Origin_TaskID', columns='Destn_TaskID', values='AvgKM').fillna(0)
data['dist_matrix'] = df.pivot_table(index='Origin_TaskID', columns='Destn_TaskID', values='AvgTime').fillna(0)
I am using Google OR Tools for solving the capacitated vehicle routing problem with pickups and deliveries. I am importing distance matrix from MSSQL database and struggling to formulate the distance matrix.
Following are the tasks to be delivered :
taskid SiteID
CFR CFRC21126412A8612122
CFRORFC2207-002969 CFRC21126412A8612122
CFRORFC2207-003940 CFRC21085782A8615004
DC VISIT CFRP30036
We also have times and distance in database, hence formulated the matrix as such:
Just struggling to see how I can output this to distance and time matrix as per required by VRP . Following is my drafted code :
with sqlConn.cursor() as cursor:
cursor.execute('EXEC [dbo].[get_Active_Tasks_Origin_Destination]')
result = cursor.fetchall()
dd=[]
for i in range(len(tasks)):
row=[]
for j in range(len(tasks)): ##what to loop here
print("dat i j={}".format(result[i][3])) ##need to get Average KM or Time here
row.append(result[i][4])
dd.append(row)
print(type(dd[0][1]))
Following is my result[i]
result[i]
('CFR', 'CFRORFC2207-003940', 'CFRC21126412A8612122', 'CFRC21085782A8615004', 0.297, 0.0399742)
Just struggling to see how I can output this to distance and time matrix as per required by VRP .
When using OR-tools to solve VRP, you don’t necessarily need a distance or time matrix. You can provide a callback to calculate the distance between two nodes. This allows you the freedom to represent the distance in any way you want.
Here are some options:
-
A 2D list. Let’s call it
mat
. Then you get the distance from nodei
to nodej
by doingmat[i][j]
. The limitation is thati
andj
must be integers. -
Nested dictionaries. This uses the exact same syntax as a 2D list, but now
i
andj
can be whatever type you want (as long as it is hashable). So for example, you can use strings as the indexes. -
Use the dataframe directly. Both of the other options require that you transform your dataframe into another data structure. You can use the dataframe directly and implement logic to get the distance from it.
Source: https://developers.google.com/optimization/routing/vrp
Following is my eventual solution:
-
Store the results in Panda’s DataFrame
with sqlConn.cursor() as cursor: cursor.execute(f'EXEC [dbo].[get_Active_Tasks_Origin_Destination_v2] ?', str(tenantid_num)) df = pd.DataFrame.from_records(cursor.fetchall(), columns = [desc[0] for desc in cursor.description]) cursor.close()
-
Use the pivot_table method to create the matrix
data['time_matrix'] = df.pivot_table(index='Origin_TaskID', columns='Destn_TaskID', values='AvgKM').fillna(0) data['dist_matrix'] = df.pivot_table(index='Origin_TaskID', columns='Destn_TaskID', values='AvgTime').fillna(0)