GTFS - 改进两个Feed中的旅行搜索

时间:2017-03-11 15:50:43

标签: java gtfs

我目前正在开发一个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时,这是完成的。

1 个答案:

答案 0 :(得分:1)

我不知道GTFS,但是,也许你可以将我的解决方案翻译成它。我要做的是为第二个Feed构建一个这样的Map:

Map<StopTime, List<Trip>> tripsByStopTime;

您可以通过这样的第二个Feed来完成此操作(例如,只要您获得上面的地图,就可以按照您喜欢的方式执行此操作) - 因为我使用StopTime作为密钥,请确保其具有正确的equalshashCode

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.
        }
    }
}

你也可以把它作为一个流写得非常好。