【问题标题】:PostgreSQL - Shortest PathPostgreSQL - 最短路径
【发布时间】:2017-11-19 14:14:07
【问题描述】:

我有一个网格表,它存储一个起点和一个目标点。 它看起来像这样:

  src  | dest  | cost 
-------+-------+------
 {1,1} | {1,2} |    1
 {1,1} | {2,1} |    1
 {1,2} | {1,1} |    1
 {1,2} | {1,3} |    1
 {1,2} | {2,2} |    1
 ...
 {4,5} | {5,5} |    1

我想从我的起点开始,然后走到它的一个邻居,然后到他的邻居等等。

到目前为止我有这段代码(计数器只是为了确保我不会陷入无限循环):

WITH RECURSIVE

init (here, there, cost_to_here, counter, path ) AS (
SELECT g.src, g.dest, 0.0, 1, array[g.src, g.dest]  -- SourcePoint with a cost of 0 src -> src
FROM grid AS g
WHERE g.src = '{1,1}'

UNION ALL

(WITH init(here, there, cost_to_here, counter, path) AS (TABLE init)  -- Reference the working Table once

SELECT g.src, g.dest, i1.cost_to_here + g.cost, i1.counter + 1, i1.path || array[g.dest]
FROM grid AS g, init AS i1
WHERE g.src = i1.there
AND NOT g.dest = ANY(i1.path)
AND (i1.here) IN (select i2.here
                   from init as i2)
and i1.counter < 7


 )
)
table init;

我从我的 src 点开始,即{1,1} 并访问它的邻居。因为我不想回到我已经访问过的点,所以我检查我是否已经访问过我的下一个点。

这就是代码的作用:

 here  | there | cost_to_here | counter |                               path                                
-------+-------+--------------+---------+--------------------------------------
 {1,1} | {1,2} |          0.0 |       1 | {"{1,1}","{1,2}"}
 {1,1} | {2,1} |          0.0 |       1 | {"{1,1}","{2,1}"}
 {1,2} | {1,3} |          1.0 |       2 | {"{1,1}","{1,2}","{1,3}"}
 {1,2} | {2,2} |          1.0 |       2 | {"{1,1}","{1,2}","{2,2}"}
 {2,1} | {2,2} |          1.0 |       2 | {"{1,1}","{2,1}","{2,2}"}
 ...
 {1,2} | {1,3} |          3.0 |       4 | {"{1,1}","{2,1}","{2,2}","{1,2}","{1,3}"}
 {2,3} | {1,3} |          3.0 |       4 | {"{1,1}","{1,2}","{2,2}","{2,3}","{1,3}"}

如您所见,它为我生成了通往{1,3} 的不同路径。我怎样才能设法只保留最好的?

但我只想保持最好的路径。 我该如何处理?

【问题讨论】:

标签: sql postgresql


【解决方案1】:

之后,只保留最短的那个。像这样的:

select distinct on (src, dest) i.*
from init 8
order by src, dest, cost_to_here;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    • 2014-08-07
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多