在python中加速此递归过程
给定一个图H,我必须找到所有满足特殊需求(我称之为需求2)的图g。所有这些图都存储在一个集合s中。图g必须具有与H相同的顶点数,并且所有图都是有向图。所以本质上,我在寻找可以添加到g中的边,以满足要求2。我使用字典为我的图表做记号,例如:在python中加速此递归过程,python,performance,recursion,graph,Python,Performance,Recursion,Graph,给定一个图H,我必须找到所有满足特殊需求(我称之为需求2)的图g。所有这些图都存储在一个集合s中。图g必须具有与H相同的顶点数,并且所有图都是有向图。所以本质上,我在寻找可以添加到g中的边,以满足要求2。我使用字典为我的图表做记号,例如: H = { '1': {'1': set([(0, 1)])}, '3': {'3': set([(0, 1)]), '2': set([(0, 1)])}, '2': {'1': set([(0, 1)]), '3': set([(0, 1)]), '2':
H = {
'1': {'1': set([(0, 1)])},
'3': {'3': set([(0, 1)]), '2': set([(0, 1)])},
'2': {'1': set([(0, 1)]), '3': set([(0, 1)]), '2': set([(0, 1)])},
}
表示顶点1到1之间有一条边,顶点3到2之间有一条边等等。请暂时忽略集合([(0,1)]),因为它们与我的问题无关。为了找到满足需求2的这些g,我向一个顶点数与H相同的空图g中添加一条边,然后使用需求1得到一组边,我知道这些边可能用于满足需求2。然后,我将要求1认为合适的一条边添加到g和测试要求2中。我不直接使用requirement2的原因是,添加g没有的每一条边,然后在其上测试requirement2太耗时了。提早修剪为我节省了时间。我继续进行深度优先搜索,如果需求1返回一个空数组,我知道我必须回溯。我当前的代码使用memoization来存储子问题解决方案,但这段代码仍然不够快……有7个节点,这段代码可能需要2500秒才能运行。任何关于如何加快这一进程的建议都将不胜感激
关于此代码使用的某些函数的更多信息:
添加边(g,e)将边e添加到g
delanedge(g,e)删除g中的边e
edgelist(g)返回g的边列表
补码(g)返回g没有的边的列表
如果g满足某些要求,则requirement1(H,g)返回T
以其他方式涉及H和F。它的目的是减少每轮需要添加的边数
如果g满足涉及H和F的某些要求,则requirement2(H,g)返回T。如果为true,则将g添加到s
备忘录存储我的子问题解决方案
gsig只是将图g转换为一种形式,我可以将其添加到集合中
def findgs(H):
g = {n:{} for n in H}
s = set()
@memo
def addedges(g,H,edges):
if edges:
masks = []
for e in edges:
addanedge(g,e)
if requirement1(H,g):
masks.append(False)
else:
masks.append(True)
delanedge(g,e)
nedges = [edges[i] for i in range(len(edges)) if masks[i]]
n = len(nedges)
if n:
for i in range(n):
addanedge(g,nedges[i])
if requirement2(H,g):
s.add(gsig(g))
addedges(g,H,nedges[:i]+nedges[i+1:])
delanedge(g,nedges[i])
edges = edgelist(complement(g))
addedges(g,H,edges)
return s
def memo(func):
cache = {}
@wraps(func)
def wrap(*args):
s = tool.signature(args[0],args[2])
if s not in cache:
cache[s] = func(*args)
return cache[s]
return wrap
我注意到的一件事是,满足需求2的相同图形出现了很多次,并且被切掉,因为s是一个集合,不允许重复 您使用自己的特殊图形表示,而不是像
networkx
这样经过优化和测试的库,这是否有原因?因为requirement1和requirement2是由其他人编写的,并且使用该特殊图形表示