繁体   English   中英

在列表列表中的两个列表之间查找公共元素的最快方法

[英]Fastest way for finding a common element between two lists in a list of lists

我正在尝试识别有向图中的气泡结构(方向从左到右)。 我从一个可能的起始节点开始遍历图形,例如绿色节点。 然后我向所有路径添加一个节点,当路径再次发散时添加路径副本,如下所示:

第一次迭代:[[3],[7]]

第二次迭代:[[3,4],[3,5],[7,8],[7,9]]

每次迭代后,我想检查是否有任何路径相交并将它们保存为确认的气泡。 目前我正在使用嵌套的 for 循环来比较每条路径,但是路径的数量会变得非常大,因此脚本会变得非常慢。 路径的顺序很重要。

示例气泡

关于如何提高路径列表中一条路径与另一条路径的比较速度的任何建议?

def ExtendPaths(paths, outEdges):
newPaths = []
for path in paths:                                              
    nextNodes = GetNextSegment(path[len(path) - 1], outEdges)   
    if len(nextNodes) == 0:
        j=5
    else:
        for node in nextNodes:                                      
            newPath = list(path)                                    
            newPath.append(node)                                    
            newPaths.append(newPath)                    
return newPaths

def ComparePaths(paths, putativeBubbleStartSegment):
length = len(paths)
for path1 in paths:
    for path2 in paths:
        if path2 != path1:
            if len(set(path1).intersection(path2)) > 0:
                #Bubble confirmed

其中 GetNextSegment 仅返回连接到给定函数的节点的节点列表(在本例中,为路径的最后一个节点)。 outEdges 是一个字典:node:[out,going,edges]。 在 ComparePaths() 中,当 2 条路径的 .intersection() 的长度大于 0 时,确认气泡。

气泡是一种图结构,其中 2 条路径发散(例如,从绿色节点)并最终再次汇合。 在这个例子中,气泡将从 2 到 11,它们之间的所有节点。

我不是要一个完整的气泡查找算法,只是想了解如何快速将所有路径与所有其他路径进行比较。

考虑使用一组元组(如果顺序很重要)或一组frozensets(如果顺序无关紧要),而不是使用列表列表。 使用newPaths = set()初始化newPaths ,然后将每个路径添加为元组或frozenset(可散列)而不是列表:

for node in nextNodes:                                      
    newPath = tuple(path) + (node,)
    # or: newPath = frozenset(path).union({node})
    newPaths.add(newPath)

这应该可以更快地检查成员资格和交叉点。

此外,它看起来像你通过循环多次检查相同的路径paths两次。 例如,如果path1等于(3, 4)path2等于(3, 5) ,则不需要检查(3, 4)(3, 5)以及(3, 5)(3, 4) ,因为您的支票看起来是对称的。 您可以使用itertools帮助程序简化ComparePaths

from itertools import combinations

def ComparePaths(paths, putativeBubbleStartSegment):
    # This gets all combinations of paths without repeating any pairing.
    for path1, path2 in combinations(paths, 2)
        # Don't need to check the length of the intersection because an
        # empty set is always equivalent to "False" in an if statement.
        if set(path1).intersection(path2):
            # Bubble confirmed

似乎您的示例代码遗漏了一些细节(因为有未使用的函数参数和变量),但我在这里看到的似乎不适用于您要执行的操作。 因此,即使可能有其他方法来改进您的算法,也很难提出任何其他加速方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM