在python中加速这个递归过程

时间:2015-03-10 04:03:48

标签: python performance recursion graph

给定图H,我必须找到满足特殊要求的所有图g(我称之为要求2)。所有这些图都存储在一组中。图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': set([(0, 1)])},
}

表示从顶点1到1有一条边,从3到2有一条边等...请忽略现在的集合([(0,1)]),因为它们不相关我的问题。为了找到满足要求2的这些g,我向具有与H相同数量的顶点的空图g添加边,然后使用requirement1来获得我知道可能用于满足要求2的边数组。然后我添加其中一个被Requirements1认为正确的边缘到g并测试require2。为什么我不直接使用要求2是添加g没有的每个边缘然后测试其上的需求2会花费太多时间。早期修剪为我节省了时间。我继续深度优先搜索,如果需求1返回一个空数组,我知道我必须回溯。我当前的代码使用memoization存储子问题解决方案,但这段代码仍然不够快......有7个节点,这段代码可能需要2500秒才能运行。任何关于如何加快这一点的建议将不胜感激。

关于此代码使用的某些函数的更多内容:

addanedge(g,e)将边e添加到g

delanedge(g,e)删除边缘e in g

edgelist(g)返回g

的边缘列表

补码(g)返回g没有的边缘列表

如果g满足某些要求,则

requirement1(H,g)返回T. 否则涉及H和F.它的目的是修剪每轮需要添加的边数。

如果g满足某些涉及H和F的要求,则

要求2(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是一个集合,不允许重复。

0 个答案:

没有答案