Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中加速此递归过程_Python_Performance_Recursion_Graph - Fatal编程技术网

在python中加速此递归过程

在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,我必须找到所有满足特殊需求(我称之为需求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': 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是由其他人编写的,并且使用该特殊图形表示