OSMnx与NetworkX最短路径计算差异:path_OX_T为何未达预期?
关于OSMnx与NetworkX最短路径计算结果的疑问
尝试用多种方法计算最短路径时得到了不同结果(符合预期),但对每种方法的运行逻辑存疑。以法国安纳西(Annecy)为例,用NetworkX和OSMnx的Dijkstra算法得到了如下结果:
计算代码
import osmnx as ox import networkx as nx Cities = ['Annecy, France','Epagny Metz-Tessy, France'] graph_city = ox.graph_from_place(Cities, network_type='drive', simplify=True, truncate_by_edge=False, clean_periphery =True) graph_city = ox.project_graph(graph_city) graph_city = ox.consolidate_intersections(graph_city, rebuild_graph=True, tolerance=15, dead_ends=True) graph_city = ox.add_edge_speeds(graph_city) graph_city = ox.add_edge_travel_times(graph_city) DEP_node = 530 ARR_node = 549 path_NX = nx.dijkstra_path(graph_city, DEP_node, ARR_node) path_OX_L = ox.shortest_path(graph_city, DEP_node, ARR_node, weight='length') path_OX_T = ox.shortest_path(graph_city, DEP_node, ARR_node, weight='time') fig, ax = ox.plot_graph_routes(graph_city, [path_NX,path_OX_L,path_OX_T], route_colors=['r','g','y'], route_linewidth=4,node_size=1, figsize=(7,7), bgcolor='#FFFFFF', node_color='#111111')
路径时间与长度统计代码
Time = int(sum(ox.utils_graph.get_route_edge_attributes(graph_city,path, 'travel_time'))) Length = int(sum(ox.utils_graph.get_route_edge_attributes(graph_city, path, 'length')))
计算结果
| path_NX | path_OX_L | path_OX_T | |
|---|---|---|---|
| TIME | 238 | 211 | 238 |
| LENGTH | 2136 | 1959 | 2136 |
可以看到,以length为权重通过OSMnx计算的path_OX_L不仅路径长度最短,耗时也更短。那本应追求最快的path_OX_T为何未达到预期效果?
问题原因分析
NetworkX默认权重逻辑:
nx.dijkstra_path未指定weight参数时,会优先使用边的weight属性;若图中无该属性,则每条边权重视为1。你的结果中path_NX与path_OX_T完全一致,说明图中默认的weight属性和travel_time等价,或者在图构建过程中weight被映射为旅行时间。path_OX_T未最优的核心原因:
OSMnx的shortest_path指定weight='time'时,严格基于边的travel_time属性计算,但这里出现反直觉结果,本质是道路速度属性的赋值问题:ox.add_edge_speeds()默认根据道路类型(如主干道、支路)分配预设速度,而非OSM数据中的实际限速。如果path_OX_L经过的道路被赋予的默认速度不低于path_OX_T的道路,那么更短的路径自然耗时更少。travel_time由length / speed计算得出,若短路径的道路等级更高(默认速度更快),其总耗时会比更长但速度慢的路径更短,这就导致path_OX_L的时间优于path_OX_T。
验证与优化建议:
- 对比两条路径的道路速度差异,确认速度赋值是否合理:
# 获取两条路径的边速度 speeds_L = ox.utils_graph.get_route_edge_attributes(graph_city, path_OX_L, 'speed_kph') speeds_T = ox.utils_graph.get_route_edge_attributes(graph_city, path_OX_T, 'speed_kph') print(f"path_OX_L平均速度: {sum(speeds_L)/len(speeds_L):.1f} km/h") print(f"path_OX_T平均速度: {sum(speeds_T)/len(speeds_T):.1f} km/h") - 若需要更精准的旅行时间,建议使用包含实际限速的OSM数据,或手动修正道路的
speed_kph属性后再计算最短路径。
- 对比两条路径的道路速度差异,确认速度赋值是否合理:
内容的提问来源于stack exchange,提问作者AliStonks
相关产品推荐
相关产品推荐

