我正在寻找解决方案,但是找不到解决方法。
我的目标是根据公交车之间的时间找到2个公交车站之间的最短路程。
所以我有总线和每个时间表。成本由实际公交车站和下一个公交车站之间的时间差(以秒为单位)表示。来源和目标是巴士站的ID
问题是:我有一些并行链接,因为每辆公共汽车每天多次排队,每次都以相同的方式运行。
我尝试过使用pgrouting的shortest_path函数,但由于并行链接,它会多次返回错误的解决方案。
我见过关于shooting_star,但我不认为我可以在没有几何体的情况下使用它。
我使用PostGIS 2.0.1获得PostGreSQL 9.1.9。以下是我的数据库提取示例:
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
答案 0 :(得分:1)
除了一条公交线路的多个实例的问题之外,这个带rCTE (recursive Common Table Expression)的查询解决了所述的问题:
我的目标是找到两个巴士站之间的最短路径,基于 公共汽车在他们之间的时间。
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;
<强> -> SQLfiddle 强> demo.
您可以在此过程中轻松收集更多信息。
算法遍历每个连接,并检查它是否已经存在(放弃)或者它是否已到达(成功)。然后选择最短的成功途径。
这适用于中小型基数。但是,对于大表,不能很好地扩展,因为每个可能的路径(不进入圆圈)都会被尝试。递归CTE无法检查另一条路径是否已在较短时间内成功。通过消除已经花费太长时间的所有路由,专用算法可以更好地执行。您可以使用plpgsql函数执行此操作,但在C中实现它会快得多。