问题描述
我正在使用纽约出租车数据集。街道网络是使用osmnx获得的,红色点是出租车的GPS位置。
我做了一些地图匹配。我将GPS位置投影到其最接近的边缘,并将投影视为节点并添加到网络(图形),其边缘也进行了相应更新。我得到以下网络。黄色的点是真实的节点,紫色的点是GPS位置的投影(也被视为节点,但通过其属性来区分)。
下一步,我想找到两个紫色点之间的最短路径。例如,我得到以下内容。
红线显然不是最短的路径。在我看来,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)
,
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