乘公共汽车旅行

时间:2013-07-08 18:34:04

标签: algorithm

  

如果你有一个国家的完整公交时刻表,你怎么能找到   最远的人可以在一天内旅行而不会两次去同一站吗?

我假设公交时刻表为您提供每个公交车站的离港和到达时间的完整列表。

缓慢而天真的方法如下。

您当然可以根据公交车时刻表制作一张图表,并在公交车站之间设置多个有向边。然后,您可以进行深度优先搜索,记住您到达每个节点所花费的边缘的到达时间,并且仅在您到达那里之后离开该止挡的边缘。如果你去过一个你曾经去过的节点,你只能在那里继续,如果你的遍历中的当前时间是你之前访问过该节点的最早时间之前。您可以记录每个节点可以获得的最远距离,然后您可以检查每个节点以找到您可以整体旅行的最远距离。

然而,这似乎非常低效,并且它实际上不是正常的图形问题。问题是在正常的有向图中,如果你可以从A到B,从B到C,那么你可以从A到C.这里不是这样。

你能解决这个问题的最快速度是什么?

5 个答案:

答案 0 :(得分:8)

我认为你原来的算法非常好。

在尝试查找每个节点的最短路径时,您可以将您的方法视为Dijkstra's algorithm的版本。

请注意,在此阶段最好根据时间对图表中的边缘进行加权。我们的想法是使用类似Dijkstra的算法计算在1天内可达到的所有节点,然后从起点选择空间中最远的节点。

Dijkstra的实现可以使用堆来检索要在O(logn)中探索的下一个节点,我认为这对您的方法也是一个很好的增强。如果您始终选择最早可以达到的节点,则永远不需要重复该节点的计算。

总的来说,方法是:

  1. 每个起点
  2. 使用修改后的Dijkstra计算1天内可到达的所有节点
  3. 找到所有这些节点中最远的空间。
  4. 因此,对于n个起点和e总线路径,复杂度约为O(n(n + e)log(n)),以获得最佳答案。

    通过在A* search中使用适当的启发式,您应该能够提高性能。启发式需要低估一点的最大可能距离,因此您可以使用总线的最大速度乘以剩余时间。

答案 1 :(得分:4)

您可以为每个位置/时间创建多个节点,而不是为每个离开某个位置创建多个边缘。

  1. 每个出发时间为每个位置创建一个节点。
  2. 每个到达时间为每个位置创建一个节点。
  3. 创建边缘以将出发连接到抵达。
  4. 创建边缘以将给定节点连接到最近未来时间属于同一位置的节点。
  5. 通过这样做,您可以遍历图表的任何路径都是“有效的”(意味着旅行者可以通过公共汽车旅行的组合或选择坐在某个位置并等待未来的公共汽车来实现这一目标)。

答案 2 :(得分:2)

简单的图表表示不起作用。 I. e。每个城市都是一个节点,边缘代表时间。这是因为“边缘”并不总是有效 - 它只在一天中的某些时间有效。

想到的第二件事是Edward Tufte的巴黎火车时刻表Paris Train Schedule,这是一种不同的图表。但这也不适合这个问题。根据列车时刻表,车站之间有连续的关系,但一般情况下,城市和公交车时刻表并非如此。

但是Tufte激发了以下方式将其建模为图形。您只能编写代码来构造图形并使用包含最短路径算法的标准图形库。

  • 每次巴士旅行均为重量=距离覆盖的边缘
  • 每个(城市,出发)和(城市,到达)是一个节点
  • 给定城市的所有节点都按时间顺序依次通过零权重边连接,忽略它是到达还是离开。该子图看起来像一个链。
  • (这是有向图)

线性时间解决方案:请注意,图表将是有向的非循环图。在这样的图中找到最长的路径是linear“加权图G中两个给定顶点s和t之间的最长路径与图G中的最短路径相同 - 通过将每个权重改为其否定来从G导出。因此,如果最短路径可以是在-G中找到,然后在G中也可以找到最长的路径。“

希望这有帮助!如果有人可以发布图表的可视化,那就太好了。如果我自己可以这样做,我会再做一次编辑。

答案 3 :(得分:2)

很抱歉,但如上所述,此问题的复杂性非常高。最初误解了这个问题并且认为它是np-hard,但事实并非如此。然而它确实具有相当高的复杂性,我个人不想处理。这个算法是一个非常好的近似,可以节省相当多的复杂性,我个人认为值得。

然而,如果你想要的只是一个“相当不错”的答案,那里有很多相当有效的算法会非常快速地接近。

我个人建议在这里使用一个简单的贪婪算法。

我已经在一些(授予的,小的和人为的)示例上做到了这一点,并且效果很好并且效率nlog(n)

  • velocity与每个节点相关联,速度是您离开给定节点最快的速度。在我的例子中,这个速度是distance_travelled/(wait_time + travel_time)。我使用离开节点的所有行程的最大速度作为该节点的速度分数。
  • 从您的节点/时间计算所有相邻节点的速度并前往“最快”节点。

这种算法非常适合复杂性,因为它基本上将问题转换为静态搜索,但是根据您的数据集,可能会有一些潜在的陷阱需要调整。

这个算法最大的问题是真正快速的公共汽车进入中间地带的可能性。您可以通过在速度计算中添加“流行度”术语来解决这个问题(有效地更快地制作更受欢迎的停靠点),但是根据您的数据集可以轻松地使事情变得更好或更糟。

答案 4 :(得分:-1)

天真是你得到的最好的 - http://en.wikipedia.org/wiki/Longest_path_problem

编辑:

所以问题有两个。

  1. 创建一个图表列表,其中可以从pointA行进到pointB。可能的是busA从pointA到pointB的可用时间。

  2. 从上面所有可能生成的路径中找到最长路径。

  3. 另一种方法是在每个节点遍历时重新评估图形并找到最长路径。 它仍然会减少找到最长的路径,即NP-Hard。