我目前正在开发一个java程序,它接收两个feed并打印出任何一个feed中缺少的行程或者部分在其中的行程。例如,进给1具有行程T1,停止ABCDE,进给2具有行程T2,停止ABCD。所以T2是T1的子集。
每个Feed基本上都有一个Map<Type, List<Trip>>
。 Type是路线类型(公共汽车,有轨电车等),List<Trip>
包含该类型的所有行程。
所有Trip
个对象都包含指定的字段here。还有对List<StopTime>
和Service
的引用,它指定按行排序的停靠点和行程运行时的服务时间。
检查按预期工作,我得到了我期望的结果。但是使用大型馈送(40.000次和更多次)的运行时间相当长,因为我基本上检查一个列表中的每个行程,而另一个列表在最坏的情况下是O(n ^ 2),如果我没有弄错的话。
我正在寻找一种方法来尽量减少我要看的行程。
我可以做的一件事是,如果行程的日期范围重叠,则移动检查。当前检查List<StopTime>
对象中的Trip
时,这是完成的。
答案 0 :(得分:1)
我不知道GTFS,但是,也许你可以将我的解决方案翻译成它。我要做的是为第二个Feed构建一个这样的Map:
Map<StopTime, List<Trip>> tripsByStopTime;
您可以通过这样的第二个Feed来完成此操作(例如,只要您获得上面的地图,就可以按照您喜欢的方式执行此操作) - 因为我使用StopTime
作为密钥,请确保其具有正确的equals
和hashCode
:
for (List<Trip> trips : feed2.values()) {
for (Trip trip : trips) {
for (StopTime stopTime : trip.getStopTimes()) {
tripsByStopTime.computeIfAbsent(stopTime, k -> new ArrayList<>())
.add(trip);
}
}
}
现在您有了这张地图,您可以更快地检查潜在的匹配行程,因为只考虑至少有一个匹配的停留时间(注意我假设停止时间相当独特,如果大多数是重复这种方法不能很好地扩展):
for (List<Trip> trips : feed1.values()) {
for (Trip trip : trips) {
Set<Trip> potentialMatchingTrips = new HashSet<>();
for (StopTime stopTime : trip.getStopTimes()) {
List<Trip> list = tripsByStopTime.get(stopTime);
if (list != null) {
potentialMatchingTrips.add(list);
}
}
for (Trip potentialMatchingTrip : potentialMatchingTrips) {
// Check here if it was a subset.
}
}
}
你也可以把它作为一个流写得非常好。