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

OSMNX中如何实现同时按路径长度与通行时间优化路线?

距离与通行时间联合优化最优路线实现方案

OSMnx的最短路径接口底层依赖NetworkX的单源最短路径算法,仅支持单一边权重输入,要同时优化距离、通行时间两个目标,最易落地的方案是将两个维度的属性做归一化后,按偏好权重融合为单一边权重,再传入最短路径接口计算即可。

核心实现步骤

  • 先对边的长度、通行时间做Min-Max归一化,消除两个属性的量纲、数值量级差异,避免某一属性完全主导权重结果
  • 根据自身优化偏好设置两个目标的权重占比(两个权重之和为1):
    • 偏好更快到达:调高通行时间的权重占比
    • 偏好更短路程:调高距离的权重占比
    • 两个目标同等重要:两个权重各设为0.5
  • 为路网每条边计算融合后的自定义组合权重
  • 调用最短路径接口时,将weight参数指定为自定义的组合权重字段即可

如果需要获取所有严格帕累托最优的路线(即不存在另一条路线同时比当前路线更短、更快),可以将通行时间的权重占比从0到1按固定步长遍历,每次计算对应路线后去重,就能得到帕累托前沿上的所有候选路线。

可直接运行的修改后代码

import numpy as np
import osmnx as ox

origin = (-33.4667,-70.7208)
destiny = (-33.367204, -70.506080) 

# 若路网未预先计算通行时间属性,先执行以下两行
# graph = ox.add_edge_speeds(graph)
# graph = ox.add_edge_travel_times(graph)

# --------------------------
# 自定义组合权重计算逻辑
# --------------------------
# 提取全图边的属性值用于归一化
all_edge_lengths = []
all_edge_times = []
for _, _, edge_data in graph.edges(data=True):
    all_edge_lengths.append(edge_data["length"])
    all_edge_times.append(edge_data["time"])

# 计算归一化基准值
len_min, len_max = np.min(all_edge_lengths), np.max(all_edge_lengths)
time_min, time_max = np.min(all_edge_times), np.max(all_edge_times)

# 设置两个目标的权重占比,可按需调整,二者之和必须为1
alpha = 0.6  # 通行时间权重占比60%
beta = 0.4   # 距离权重占比40%

# 为每条边生成融合后的组合权重
for _, _, edge_data in graph.edges(data=True):
    norm_len = (edge_data["length"] - len_min) / (len_max - len_min)
    norm_time = (edge_data["time"] - time_min) / (time_max - time_min)
    edge_data["combined_weight"] = alpha * norm_time + beta * norm_len
# --------------------------

orig_node = ox.distance.nearest_nodes(graph, origin[1], origin[0])
target_node = ox.distance.nearest_nodes(graph, destiny[1], destiny[0])

# 最短路径计算使用自定义的组合权重
route = ox.distance.shortest_path(graph, orig_node, target_node, weight="combined_weight")

length = int(sum(ox.utils_graph.get_route_edge_attributes(graph, route, "length")))
time = int(sum(ox.utils_graph.get_route_edge_attributes(graph, route, "time")))

print('Distancia: ',length/1000,' km')
print('Tiempo: ',time/60,' min')
ox.folium.plot_route_folium(graph, route, route_map=None, popup_attribute=None, tiles='cartodbpositron', zoom=1, fit_bounds=True)

注意:不可跳过归一化步骤。如果直接将原始单位的长度、时间数值相加,米级的长度数值会远大于秒级的时间数值,最终权重会完全被距离主导,无法达到联合优化的效果。

内容的提问来源于stack exchange,提问作者Jorge Esteban Reyes Marambio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 09:15:43