考虑以下有向图:
>>> g
array([[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[1, 0, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 0]])
此图表包含周期0 -> 1 -> 2 -> 0
。使用scipy.sparse.csgraph.shortest_path
我可以找出节点之间的距离:
>>> d = csgraph.shortest_path(g)
>>> d
array([[ 0., 1., 2., inf, inf],
[ 2., 0., 1., inf, inf],
[ 1., 2., 0., inf, inf],
[inf, inf, inf, 0., 1.],
[inf, inf, inf, inf, 0.]])
然后,我可以通过检查是否存在相反的连接i -> j (i != j)
j -> i
来检测该图中的周期:
>>> d + d.T
array([[ 0., 3., 3., inf, inf],
[ 3., 0., 3., inf, inf],
[ 3., 3., 0., inf, inf],
[inf, inf, inf, 0., inf],
[inf, inf, inf, inf, 0.]])
对于单个循环,我可以通过检查相应连接的“edge-head”索引来获取相应的节点:
>>> np.unique(np.argwhere(
... (cycles > 0)
... & (cycles != np.inf)
... )[:, 0])
array([0, 1, 2])
但是,如果图形包含多个周期(可能具有相同的长度),例如:
>>> g
array([[0, 1, 0, 0, 0],
[1, 0, 0, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]])
包含周期0 -> 1 -> 0
和2 -> 3 -> 2
。使用上述方法我无法区分两个不同的周期。
我觉得选项csgraph.shortest_path(..., return_predecessors=True)
和scipy.sparse.csgraph.reconstruct_path
可能会有所帮助,但我仍然没有看到区分这两个周期的方法,csgraph.reconstruct_path
期望前导列表,而csgraph.shortest_path
返回相应的矩阵。
那么有没有办法通过使用scipy.csgraph
提供的函数从图表中获取所有周期?