Поиск кратчайшего пути в SQL от одной вершины до всех
Пишу алгоритм нахождения кратчайшего пути(С минимальным весом) от вершины S до всех остальных, понимаю, в чём ошибка : минимальный путь до одной вершины не является минимальным для другой, это и сбивает алгоритм как можно исправить код ? Код:
-- Код для поиска всех кратчайших путей от вершины S
with recursive temp AS
(select id,
array [id] as path,
0 as price,
false as cycle
from "DbWorkHierarchy"
where id = 'S'
UNION ALL
SELECT "DbWorkHierarchy".id,
temp.path || "DbWorkHierarchy".id as path,
temp.price + "DbWorkHierarchy".weight as price,
"DbWorkHierarchy".id = any (temp.path) as cycle
from "DbWorkHierarchy"
JOIN temp on (temp.id = "DbWorkHierarchy".par_id) AND NOT cycle)
select id as edge, path as nodes, price as cost
from temp
where id
-- Выбор всех вершин, до которых дошел
in (SELECT id as edge from temp group by id)
--выбор самой малой цены, за которую дошел до вершин
and price in (
SELECT min(price) as cost
from temp
group by id)
;
Я пробовал перебрать все вершины в цикле:
DO
$do$
DECLARE
x varchar;
/*array1 varchar[]:= array['S','U','X','V','Y'];*/
BEGIN
foreach x in array ['S','U','X','V','Y']
LOOP
with recursive temp AS
(select id,
array [id] as path,
0 as price,
false as cycle
from "DbWorkHierarchy"
where id = 'S'
UNION ALL
SELECT "DbWorkHierarchy".id,
temp.path || "DbWorkHierarchy".id as path,
temp.price + "DbWorkHierarchy".weight as price,
"DbWorkHierarchy".id = any (temp.path) as cycle
from "DbWorkHierarchy"
JOIN temp on (temp.id = "DbWorkHierarchy".par_id
) AND NOT cycle)
SELECT id as edge, path as nodes, price as cost
from temp
where id = x
and price in (select min(price) from temp where id = x);
END LOOP;
END;
$do$;
Но получаю ошибку :[42601] ОШИБКА: ошибка синтаксиса (примерное положение: "["
Примечание: Граф ориентирован, направление от par_id к id
UPD код для создания и заполнения таблицы :
create table DbWorkHierarchy (
id varchar,
par_id varchar,
weight integer
);
insert into DbWorkHierarchy (id, par_id, weight) VALUES ('X', 'S',5)
,('U', 'S',3),
('Y','V',2),
('X','U',2)
,('Y','X',6),
('S','Y',3),
('V','Y',7),
('U','X',1),
('V','U',9),
('V','X',4),
('T','X',4),
('V','T',2);
UPD: SQL Fiddle URL : http://sqlfiddle.com/#!17/ba262/2
