我有一对存储在元组中的整数(例如(1,2) (4,5) ...
)。这些元组存储在列表中。
我试图在这些元组中找到这种模式(1,2) (2,3) (3,4) (4,1)
,它以任何整数开始,然后从元组的第二个整数跳转到另一个元组的第一个,以整数结束在开始时被接走了。
每个模式都存储在一个集合中。然后我将第一个整数和相关模式存储为键/值对。我的例子就是:dictionary={1:set([1,2,3,4]),...}
然后我合并了具有共同项目的模式。例如,(1,2) (2,3) (3,1)
和(2,4) (4,1)
合并到此集合中:set([1,2,3,4])。我删除了其中一个键。
这是我的代码:
from collections import defaultdict
dictio_chaine=defaultdict(set)
for item1 in A: # A is the list containing the afore mentioned tuples
a,b=item1
l=[a,b]
for item2 in A:
if item2[0]==b and b!=a:
b=item2[1]
l.append(b)
if b==a:
break
if l[-1]==a:
dictio_chaine[a].update(l)
liste=combinations(dictio_chaine.iterkeys(),2) #The following piece of code merges the
for item in liste: #overlapping patterns.
if item[0] in dictio_chaine and item[1] in dictio_chaine:
if dictio_chaine[item[0]]&dictio_chaine[item[1]]:
dictio_chaine[item[0]].update(dictio_chaine[item[1]])
del dictio_chaine[item[1]]
我遇到了以下问题:我的算法的第一部分,它在元组列表中找到模式,因为它的性能是O(n ^ 2),所以非常差。
我认为创建一棵树会更好。模式(1,2) (2,3) (3,1)
变为2 is the child of 1, 3 is the child of 2 ...
然后如果遇到模式(2,5) (5,2)
,它就变成了一个新的分支5,它是2的子节点,它已经是1的子节点。最后,我将合并成一个具有相同叶子的单个分支。第一个节点。
会更好吗?我怎么能实现这样一棵树,因为我能轻易实现的唯一树是一棵二叉树,它根本不适合我正在尝试做的事情。
您有什么建议可以帮助我改进算法吗?
答案 0 :(得分:2)
如果我理解了这个问题,那么您正试图在有向图中找到简单的循环。
换句话说,您可以将诸如(4,5)之类的元组解释为表示节点4和节点5之间的有向边。然后,您将尝试查找从节点开始的路径,其中包含许多edge,并返回起始节点。
您可以使用Python库simple_cycles中的函数NetworkX轻松完成此操作。例如,
>>> import networkx as nx
>>> G = nx.DiGraph([(0, 0), (0, 1), (0, 2), (1, 2), (2, 0), (2, 1), (2, 2)])
>>> list(nx.simple_cycles(G))
[[2], [2, 1], [2, 0], [2, 0, 1], [0]]
n个节点,e边缘和c的时间复杂度为O((n + e)(c + 1)) 基本电路。