sqlite 是否有一种有效的方法可以使用SQL在有向图中获取从给定节点到所有连接节点的路径?[duplicate]

91zkwejq  于 2023-03-08  发布在  SQLite
关注(0)|答案(1)|浏览(110)
    • 此问题在此处已有答案**:

basic recursive query on sqlite3?(5个答案)
9天前关闭。
这篇文章是编辑和提交审查5天前。
假设我们有一个大型SQLite表edge``CREATE TABLE edge(from TEXT, to TEXT),其中包含有向图的所有边(可能是循环的)。图中的每个节点都有一个唯一的id,类型为TEXT。我们如何高效地找到从给定节点到所有连接节点的所有路径?如果有多条路径连接2个节点,则只需要1条路径。由于图非常大,首先获得所有可能的路径并通过检查开始/结束对来去除重复是不够有效的。

例如,如果给定节点是A,则结果(不唯一)应如下所示。

A->B
A->B->E
A->B->E->C
A->F

我提出了一个递归CTE的解决方案,但是如果表太大,它会变得非常慢。看起来我们只能对CTE的所有列进行UNION,这使得递归搜索非常无效。

WITH RECURSIVE cte(to, chain) AS (
    SELECT edge.to, edge.to || '->' || edge.from FROM edge
        WHERE edge.from = 'A'
    UNION ALL
    SELECT edge.to, edge.to || '->' || cte.chain FROM edge
        JOIN cte
        ON cte.to = edge.from
)
SELECT MIN(chain) as selected_chain FROM cte
GROUP BY cte.to
ORDER BY selected_chain
xpszyzbs

xpszyzbs1#

我认为最好的方法是多遍解决方案。第一步:使用A-〉B和A-〉F创建临时表--换句话说,仅包含起始节点等于起始节点的行。在后续的每一步中,插入起始节点等于临时表中任意终止节点且新的终止节点尚未在表中的所有行。要消除重复的终止节点,请选择此选项(或min,无所谓)from-node。每次传递都会为它添加的每个to-node恰好多添加一行,并且最终会添加每个可访问的to-node。一旦有了这个表,就可以在生成的简化图上实现宽度优先搜索。

相关问题