Postgresql 有公交线路和时刻表的最短路径
几天以来我一直在寻找解决方案,但找不到解决方法 我的目标是根据公共汽车在两个公共汽车站之间行驶的时间,找出两个公共汽车站之间的最短路线 所以我有公交线路,每个线路都有时间表。成本由实际公共汽车站和下一个公共汽车站之间的时间差(以秒为单位)表示。源和目标是公共汽车站的ID 问题是:我有一些并行链接,因为每辆公共汽车每天都要运行很多次线路,每次都以相同的方式运行 我尝试使用pgrouting的最短路径函数,但itt多次返回错误的解决方案,因为存在并行链接 我已经看过《流星》了,但是如果没有几何学,我想我不能把它用在我的例子中 我有PostGreSQL 9.1.9和PostGIS 2.0.1。以下是我的数据库提取示例:Postgresql 有公交线路和时刻表的最短路径,postgresql,shortest-path,bus,pgrouting,Postgresql,Shortest Path,Bus,Pgrouting,几天以来我一直在寻找解决方案,但找不到解决方法 我的目标是根据公共汽车在两个公共汽车站之间行驶的时间,找出两个公共汽车站之间的最短路线 所以我有公交线路,每个线路都有时间表。成本由实际公共汽车站和下一个公共汽车站之间的时间差(以秒为单位)表示。源和目标是公共汽车站的ID 问题是:我有一些并行链接,因为每辆公共汽车每天都要运行很多次线路,每次都以相同的方式运行 我尝试使用pgrouting的最短路径函数,但itt多次返回错误的解决方案,因为存在并行链接 我已经看过《流星》了,但是如果没有几何学,我
id | idcourse | source | target | cost |
1 | 1 | 62 | 34 | 60 |
2 | 1 | 34 | 16 | 360 |
3 | 1 | 16 | 61 | 60 |
4 | 1 | 61 | 60 | 120 |
5 | 2 | 62 | 34 | 60 |
这里的最后一行是与idcourse=1的其他线路相同的公交线路,但一小时后
以下是获取此信息的请求:
select hc.idhorairecourse as id, c.idcourse,
hc.idarret as source,
(select hc2.idarret from horairecourse hc2 where hc2.idcourse = c.idcourse and hc2.heure > hc.heure order by hc2.heure limit 1) as target,
(extract(epoch from ((select horairecourse.heure from horairecourse where horairecourse.idcourse = c.idcourse and horairecourse.heure > hc.heure order by horairecourse.heure limit 1) - hc.heure))) as cost
from course c
inner join horairecourse hc on c.idcourse = hc.idcourse
where (select horairecourse.idarret from horairecourse where horairecourse.idcourse = c.idcourse and horairecourse.heure > hc.heure order by horairecourse.heure limit 1) is not null
order by c.idcourse, hc.heure
除了一条公交线路存在多个实例的问题外,此查询使用a解决了上述问题: 我的目标是根据实际情况,找出两个公共汽车站之间的最短路线 公共汽车从他们中间经过的时间 在此过程中,您可以轻松收集更多信息 该算法遍历每个连接,并检查它在放弃之前是否存在,或者是否成功到达。然后选择最短的成功之路
这适用于中小型基数。不过,对于大桌子来说,它的伸缩性不是很好,因为尝试了每一条不绕圈子的可能路线。递归CTE无法检查另一条路由是否已在较短时间内成功。一个专门的算法可以通过消除所有已经花费了太长时间的路由来表现得更好。您可以使用plpgsql函数来实现这一点,但在C中实现会快得多。您的问题中没有任何内容表明并行链接与您的问题相关。由于没有给出绝对时间戳,您只需要每个公交路线的一个副本。只需消除重复项…不,因为我必须知道人们必须在什么时候乘坐这辆公交车才能准时到达特定的公交车站…好吧,这不是你的问题。是的,你的解决方案对你的示例非常有效,但我有500多个关系。。。有没有最短路径的解决方案?
WITH RECURSIVE
from_to AS (SELECT 34 AS _from, 60 AS _to) -- insert from & to once
, route AS (
SELECT target, ARRAY[_from, target] AS stops, cost
, (target = _to) AS arrived
FROM from_to, bus
WHERE source = _from
UNION ALL
SELECT b.target, r.stops || b.target, r.cost + b.cost
, (b.target = _to) AS arrived
FROM from_to, route r
JOIN bus b ON b.source = r.target
WHERE b.target <> ALL(stops) -- don't circle
AND r. target <> _to -- we arrived
)
SELECT stops, cost
FROM route
WHERE arrived
ORDER BY cost
LIMIT 1;