街道网络中的最短路径

问题描述

我正在使用纽约出租车数据集。街道网络是使用osmnx获得的,红色点是出租车的GPS位置。

enter image description here

我做了一些地图匹配。我将GPS位置投影到其最接近的边缘,并将投影视为节点并添加到网络(图形),其边缘也进行了相应更新。我得到以下网络。黄色的点是真实的节点,紫色的点是GPS位置的投影(也被视为节点,但通过其属性来区分)。

enter image description here

下一步,我想找到两个紫色点之间的最短路径。例如,我得到以下内容。

enter image description here

红线显然不是最短的路径。在我看来,shortest_path函数说明了边缘的方向(即,对于边缘,它总是从起点到终点)。有没有办法让我获得真正的最短路径?实际上,我只希望两点之间的网络距离最短。

我想我可以复制每个边缘,使其起点和终点颠倒。但是也许有更清洁的方法可以做到这一点?

解决方法

我找到了一种干净的方法。我可以做

route = nx.shortest_path(nx.compose(G,G.reverse(copy=False)),source=9990000067,target=9990000003,weight='length')
fig,ax = ox.plot_graph_route(nx.compose(G,route)

enter image description here

,

current answer是错误的,因为它允许以错误的方式沿着单向街行驶。实际上,您需要计算两条最短的路径:一条从起点到终点,一条从终点到起点。任一方向上的最短网络距离 是这两个方向中的最小值。

(注意:如果方向性无关紧要,因为诸如步行之类的模式不遵循街道方向性约束,则在创建图形以获取完整的图形时,请提供private static List<ExpenseOutput> calculateValue(Map<String,List<Expenses>> expensesOfAllKinds,Entry<String,List<Expenses>> expenseOfAKind) { List<Expenses> expenseOfAKindOfGrocery = expenseOfAKind.getValue(); List<Expenses> expensesOfOtherKinds = expensesOfAllKinds.entrySet().stream() .filter(expenseOfDifferentKind -> !expenseOfDifferentKind.equals(expenseOfAKind)) .map(expenseOfDifferentKind -> expenseOfDifferentKind.getValue()) .flatMap(expenseOfDifferentKind -> expenseOfDifferentKind.stream()).collect(Collectors.toList()); return expenseOfAKindOfGrocery.stream() .map(oneKindOfExpense -> mapAppropriateKindAndAddValue(oneKindOfExpense,expensesOfOtherKinds)) .flatMap(x -> x.stream()).collect(Collectors.toList()); } private static List<ExpenseOutput> mapAppropriateKindAndAddValue(Expenses expenseOfAKind,List<Expenses> expensesOfOtherKinds) { return expensesOfOtherKinds.stream() .filter(expenseOfOtherKind -> checkWhetherTheyHaveSameKind(expenseOfOtherKind,expenseOfAKind)) .map(expenseOfOtherKind -> addValueIfSameKindExists(expenseOfOtherKind,expenseOfAKind)) .collect(Collectors.toList()); } private static boolean checkWhetherTheyHaveSameKind(Expenses expenseOfOtherKind,Expenses expenseOfAKind) { List<String> expenseOfAKindList = Arrays.asList(expenseOfAKind.getKind().split(",")); List<String> expenseOfOtherKindList = Arrays.asList(expenseOfOtherKind.getKind().split(",")); return expenseOfOtherKindList.stream().allMatch(expense -> expenseOfAKindList.contains(expense)); } private static ExpenseOutput addValueIfSameKindExists(Expenses expenseOfOtherKind,Expenses expenseOfAKind) { ExpenseOutput output = new ExpenseOutput(); output.setValue(expenseOfOtherKind.getValue() + expenseOfAKind.getValue()); List<String> expenseOfAKindList = new ArrayList<>(Arrays.asList(expenseOfAKind.getKind().split(","))); List<String> expenseOfOtherKindList = new ArrayList<>(Arrays.asList(expenseOfOtherKind.getKind().split(","))); expenseOfOtherKindList.addAll(expenseOfAKindList); Set<String> finalKind = expenseOfOtherKindList.stream().collect(Collectors.toSet()); output.setKind(String.join(",",finalKind)); return output; } 之类的network_type参数双向图。)

完整的最小工作示例:

walk

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...