我有一个由关系相互连接的100000个节点的图表。 从A点到B点,只有一条可能的路径,我的模型中无法循环。
我正在寻找一个解决方案,它将指示节点列表的路径是否与第二个节点列表的路径相交
如果有交叉点,我不需要知道交叉点。
是否可以在不经过整个图表的情况下获得解决方案(一旦找到第一个节点就停止)?
节点列表1:红色节点
节点列表2:蓝色节点
由于至少有一个交叉点(黑色节点),请求必须返回true。
密码请求:
编辑:密码请求
match path=shortestPath((n1)-[r*]-(n2))
where id(n1) = node1 and id(n2) in nodesList1
with nodes(path) as nodespath1
match path=shortestPath((n1)-[r*]-(n2))
where id(n1) = node2 and id(n2) in nodesList2
with nodespath1, nodes(path) as nodespath2
with ANY (n IN nodespath1 WHERE n IN nodespath2) AS conflit
with ANY (n IN collect(conflit) WHERE n = true) AS conflit
RETURN conflit;
答案 0 :(得分:1)
由于任何一对节点之间只有一条可能的路径,我认为你的图是一棵树,你可以选择一个任意节点作为那棵树的根。
完成此操作后,线性时间预处理工作允许您在恒定时间内回答最低共同祖先查询,并且任意两个节点之间的路径包含从树上升到其最低共同祖先的路径,然后是路径下降树。让我们称之为这个峰值 - 路径两端的最低共同祖先 - 路径的最低共同祖先。
如果单个节点N在路径上,则该节点的最低共同祖先和该路径的最低共同祖先是该路径的最低共同祖先,并且该节点的最低共同祖先和其中一个末端路径是节点N.此外,如果这两个东西都成立,节点N就位于路径的最低共同祖先和路径的一端之间,所以它在路径上 - 你发现了这个在O(1)时间。
如果两条路径相交,具有最低共同祖先的路径必须在另一条路径上具有该祖先,或者它将完全在另一条路径之下 - 并且上面的段落显示了如何在时间O(1)中计算是否一个任意节点在路径上,所以我们可以通过查看任一路径的最低共同祖先是否在另一条路径上来检查路径交叉点。
答案 1 :(得分:1)
要将一组路径合并到节点池中,可以使用UNWIND n + COLLECT(DISTINCT n)。以下是调整示例查询的方法。
match path=shortestPath((n1)-[r*]-(n2))
where id(n1) = node1 and id(n2) in nodesList1
UNWIND nodes(path) as nodespath1
WITH collect(DISTINCT nodespath1) as nodespath1
match path=shortestPath((n1)-[r*]-(n2))
where id(n1) = node2 and id(n2) in nodesList2
UNWIND nodes(path) as nodespath2
WITH nodespath1, collect(DISTINCT nodespath2) as nodespath2
with ANY (n IN nodespath1 WHERE n IN nodespath2) AS conflict
RETURN conflict;
当然,在您的情况下,如果路径相交,则存在从红色到红色和蓝色的路径。到目前为止更简单
MATCH (a), (b)
WHERE id(a) in nodesList1 AND id(b) in nodesList2
// Match a c node in path to an a and a b node
MATCH (a)-[*]-(c)-[*]-(a2), (b)-[*]-(c)-[*]-(b2)
WHERE id(a2) in nodesList1 AND id(b2) in nodesList2
WITH c
LIMIT 1
RETURN (COUNT(c) == 1) as conflict