给定edge e,Python中查找包含e的路径集的最快方法是什么?

给定edge e,Python中查找包含e的路径集的最快方法是什么?,python,numpy,Python,Numpy,假设我们得到了一组源、汇和边之间的路径p(长度相同)。在python中,我用一个列表列表和一对表示,即 # source = 0, sink = 9 # Path i is giving by P[i]: P[i][j] is the node j. # Path i is giving then by the edges (P[i][0], P[i][1]), (P[i][1], P[i][2]), (P[i][2], P[i][3]), ... P = [[0, 1, 3, 5, 7, 9

假设我们得到了一组源、汇和边之间的路径
p
(长度相同)。在python中,我用一个列表列表和一对表示,即

# source = 0, sink = 9
# Path i is giving by P[i]: P[i][j] is the node j.
# Path i is giving then by the edges (P[i][0], P[i][1]), (P[i][1], P[i][2]), (P[i][2], P[i][3]), ...

P = [[0, 1, 3, 5, 7, 9], 
     [0, 1, 4, 6, 8, 9], 
     [0, 1, 3, 6, 8, 9], 
     [0, 1, 3, 5, 8, 9],
     [0, 2, 4, 6, 8, 9]]
# The edge we are looking for is (1, 3)
e = (1, 3)
由于
e=(1,3)
包含在三条路径中,
p[0]、p[2]
p[3]
,因此结果是
3

以下是我的解决方案:

def count_paths(edge, paths):
    count = 0
    for path in paths:
        edges = [(path[i], path[i + 1]) for i in range(len(path) - 1)]
        if edge in edges:
            count += 1
    return count

当路径数较大时,此函数使用
cProfile
提供
tottime
16.245
。我们能用numpy让它运行得更快吗

转换为数组,使用一次性偏移量对其进行切片,沿每行查找接收器开始和停止值,然后简单地对所需输出的计数求和,所有这些都以矢量化方式进行-

In [43]: P = np.array(P)

In [44]: ((P[:,:-1]==1) & (P[:,1:]==3)).sum()
Out[44]: 3
如果您也需要有效路径,请使用
ANY
reduced row mask来屏蔽数组-

In [16]: P[((P[:,:-1]==1) & (P[:,1:]==3)).any(1)]
Out[16]: 
array([[0, 1, 3, 5, 7, 9],
       [0, 1, 3, 6, 8, 9],
       [0, 1, 3, 5, 8, 9]])

转换为数组,使用一次性偏移量对其进行切片,沿每行查找sink start和stop值,然后简单地对所需输出的计数求和,所有这些都以矢量化方式进行-

In [43]: P = np.array(P)

In [44]: ((P[:,:-1]==1) & (P[:,1:]==3)).sum()
Out[44]: 3
如果您也需要有效路径,请使用
ANY
reduced row mask来屏蔽数组-

In [16]: P[((P[:,:-1]==1) & (P[:,1:]==3)).any(1)]
Out[16]: 
array([[0, 1, 3, 5, 7, 9],
       [0, 1, 3, 6, 8, 9],
       [0, 1, 3, 5, 8, 9]])

P是否始终是一个规则数组,每个“行”的元素数相同?是的,所有路径的长度都相同。由于您使用python,因此为了获得更高的速度,您可以使用
numpy
,因为您的路径集可以轻松转换为
numpy-ndarray
,然后您在尝试访问其元素时会获得更少的延迟。(为了进一步优化,边集也将其存储在一个数组中。像
[0,1,2,3,6,8]
这样的路径不会被计算在内,对吗?不,它不会被计算。路径
[0,1,2,3,6,8]
由边
(0,1)、(1,2)、(2,3)、(3,6,8)给出,因此边
(1,3)
不存在。P始终是一个规则数组,每个“行”的元素数相同?是的,所有路径都具有相同的长度。由于您使用python,因此为了获得更高的速度,您可以使用
numpy
,因为您的路径集可以轻松转换为
numpy-ndarray
,然后您在尝试访问其元素时获得更少的延迟。(为了进一步优化,边集也会将其存储在一个数据数组中。像
[0,1,2,3,6,8]
这样的路径不会被计算在内,对吧?不,它不会被计算在内。路径
[0,1,2,3,6,8]
是由边
(0,1)、(1,2)、(2,3)、(3,6,8)
给出的,因此边
(1,3)
不存在。