基于Every Street实现可驾驶道路有向CPP路径优化的问题求助
解决方案
1. 修复Edge格式不匹配的错误
报错的直接原因是Network.get_edge_basket函数中,处理带权重边的逻辑假设所有边都是(v, u, w)三元组,但实际传入的边列表格式不一致,导致拆包失败。
步骤1:规范传入的Edges列表
从OSMnx有向图中提取边时,明确提取起点、终点和权重(比如道路长度),确保所有边都是统一的三元组格式:
# 替换原代码中生成edges的逻辑 edges = [] for u, v, edge_data in graph.edges(data=True): # 用道路长度作为权重,无长度数据则默认1 edge_weight = edge_data.get('length', 1.0) edges.append((u, v, edge_weight))
步骤2:修正Network类的边处理逻辑
打开everystreet/network/network.py,找到get_edge_basket函数,修改第66-67行的代码:
原代码:
# Removing weights for weighted network edges = [(v, u) for v, u, w in edges] if weighted else edges
替换为:
# 处理带权重边,提取节点对(兼容任意长度的边数据) if weighted: edges = [(v, u) for v, u, *_ in edges]
这个修改会忽略三元组之外的额外数据,确保拆包时只提取节点对v和u,避免“too many values to unpack”错误。
2. 适配有向图的CPP求解逻辑
原代码是为无向图设计的,直接保留有向图后,度数平衡和欧拉路径的逻辑需要调整:
步骤1:计算有向图的节点度数
添加代码计算每个节点的入度和出度:
# 计算入度和出度 in_degree = {node: 0 for node in graph.nodes} out_degree = {node: 0 for node in graph.nodes} for u, v, _ in edges: out_degree[u] += 1 in_degree[v] += 1
步骤2:平衡有向图的度数(有向CPP核心)
有向图存在欧拉路径的条件是:
- 所有节点入度=出度;或者
- 恰好一个节点出度=入度+1(起点),一个节点入度=出度+1(终点),其余节点入度=出度
如果不满足,需要添加反向边(或重复边)来平衡度数,这部分需要替换原代码中无向图的度数平衡逻辑,改用有向图的Edmonds-Johnson算法实现。
3. 解决GPX不遵守道路方向的问题
生成路径后,需要验证每一段路径的方向是否与OSMnx图中的边方向一致:
- 在生成GPX的步骤中,检查路径中的每个节点对
(u, v)是否存在于原有的有向边中 - 如果不存在,说明路径逆着单行道走了,需要调整这段路径的方向(或在度数平衡时避免添加导致反向的边)
内容的提问来源于stack exchange,提问作者Matheus Correia
相关产品推荐
相关产品推荐

