You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows环境Docker部署OSRM下,Python实现新增节点时快速更新距离矩阵的最优方案

嘿,作为Python新手能折腾OSRM和距离矩阵已经超棒啦!先给你点个赞😉

首先得说,你之前的代码效率低的核心原因是逐个调用OSRM的directions接口——300×300就是90000次请求,每次请求都有网络延迟,400秒其实已经不算慢了。不过咱们可以用OSRM专门的Table API来解决这个问题,不管是初始计算还是新增节点,效率都会提升几个数量级!

最优解决方案:用Table API批量计算,避免重复计算

先把初始计算的效率提上去(顺便为新增节点铺路)

OSRM的Table API就是专门用来批量生成距离/时间矩阵的,一次请求就能搞定所有点对,不用循环90000次。你的初始代码可以改成这样:

from routingpy import OSRM
from routingpy.routers import options
import numpy as np

# 初始化OSRM客户端
options.default_timeout = None
client = OSRM(base_url="你的OSRM服务地址")

# 把经纬度整理成 [(经度, 纬度), ...] 的格式
existing_locations = list(zip(locations_DCA_df['Longitude'], locations_DCA_df['Latitude']))

# 一次请求获取完整的300×300距离矩阵
table_result = client.table(locations=existing_locations, profile='car')
# 转成numpy矩阵,方便后续操作
distance_matrix = np.array(table_result.distances)

这样初始计算可能只需要几秒,而不是400秒!记得把这个矩阵存到本地,比如用np.save("distance_matrix_300x300.npy", distance_matrix),下次直接加载就行。

新增节点的最快方法:只算必要的点对

当你新增一个节点时,完全不需要重新计算整个301×301矩阵,只需要算新节点和所有原有节点的双向距离,然后把这些距离插入到原矩阵里就行。具体步骤如下:

1. 准备新节点的位置

假设新节点的经纬度是new_lon和new_lat:

new_location = (new_lon, new_lat)

2. 批量计算双向距离(用Table API,一次请求搞定一组)

# 计算新节点到所有原有节点的距离
new_to_existing = client.table(
    locations=[new_location],  # 起点:新节点
    destinations=existing_locations,  # 终点:所有原有节点
    profile='car'
).distances[0]  # 取第一个结果,因为只有一个起点

# 计算所有原有节点到新节点的距离
existing_to_new = client.table(
    locations=existing_locations,  # 起点:所有原有节点
    destinations=[new_location],  # 终点:新节点
    profile='car'
).distances
# 把结果扁平化(从300×1变成一维列表)
existing_to_new = [d[0] for d in existing_to_new]

小优化:如果你的场景里没有单行道(或者可以忽略单行道),那么new_to_existing和existing_to_new是完全一样的,这时候可以只算一次,省一个请求~

3. 把新距离插入原矩阵

现在把原300×300矩阵扩展成301×301:

# 第一步:给原矩阵的每一行末尾添加「原有节点到新节点」的距离
extended_matrix = np.hstack([distance_matrix, np.array(existing_to_new).reshape(-1, 1)])

# 第二步:新增一行,内容是「新节点到所有原有节点的距离」+ [0](新节点到自己的距离为0)
new_row = np.array(new_to_existing + [0]).reshape(1, -1)

# 第三步:把新行拼接到扩展后的矩阵下面
final_matrix = np.vstack([extended_matrix, new_row])

4. 保存新矩阵

别忘了把更新后的矩阵存起来,下次新增节点直接用这个:

np.save("distance_matrix_301x301.npy", final_matrix)

最后再提个小建议

如果你后续要频繁新增节点,最好把existing_locations也存到本地(比如用pickle或者csv),这样每次新增时不用再从DataFrame里读,直接加载就行,更省时间~


内容的提问来源于stack exchange,提问作者mj_davis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:17:28