繁体   English   中英

如何提高此python代码的性能?

[英]How to improve performance of this python code?

我正在解决一个难题(查找是否存在给定自动机的输入,无论起始状态是什么,最终状态每次都相同),并编写了以下python代码。 代码中的check方法中编写了一些测试用例。 对于这些情况,程序运行得相当快。 但是,对于存在50个列表(节点)的测试用例,该程序要花很多时间才能执行。 我正在存储中间结果,以备将来使用。 有人可以查看代码并提供有关如何提高代码性能的建议吗?

from itertools import product
from copy import deepcopy

class Node:
    def __init__(self,id):
        self.id = id
        self.dict = {}

    def __str__(self):
        return str(id) + " : " + str(self.dict)

    def __repr__(self):
        return str(id) + " : " + str(self.dict)

def tryDelete(nodes,_len):
    for id in nodes:
        y = deepcopy(nodes)
        x = y[id]
        del y[id]
        for id,node in y.items():
            for input,result in node.dict.items():
                if result == x:
                    if x.dict[input] == x:
                        node.dict[input] = node
                    else:
                        node.dict[input] = x.dict[input]
                    pass
        if pathPossible(y,_len ,False) == -1:
            return x.id
    return -2

target = {}
def FindTarget(node,p):
    if len(p) == 1:
        return node.dict[p[0]]
    if node not in target or p not in target[node]:
        x = FindTarget(node,p[:-1]).dict[p[-1]]
        if node not in target:
            target[node] = {}
        target[node][p] = x
    return target[node][p]

def allSatisy(nodes,p):
    x = None
    for key,node in nodes.items():
        if x is None:
            x = FindTarget(node,p)
        elif FindTarget(node,p) != x:
            return False
    return True

def allPossiblePaths(l,n):
    #x = int(((l+1)*(l+2))/2)
    for i in range(1, n+1):
        for p in product(range(l),repeat=i):
            yield p

def pathPossible(nodes,_len ,isItereate=True):
    i = 1
    isFound = False
    for p in allPossiblePaths(_len,len(nodes)):
        if allSatisy(nodes,p):
            isFound = True
            break

    if isFound:
        return -1
    elif not isItereate:
        return -2
    else:
        return tryDelete(nodes,_len)

def answer(li):
    nodes = {}
    for i in range(len(li)):
        nodes[i] = Node(i)
    for i in range(len(li)):
        for j in range(len(li[i])):
            nodes[i].dict[j] = nodes[li[i][j]]
    return pathPossible(nodes,len(nodes[0].dict))

def check(li,ans):
    # each item in the list is a node, each item i-th in the inner list tells to what node the transition happens for input i
    x = answer(li)
    print(str(li) + " : " + str(ans) + " : " + str(x))

def main():
    check([[2,1],[2,0],[3,1],[1,0]],-1)
    check([[1,2],[1,1],[2,2]],1)
    check([[1,3,0],[1,0,2],[1,1,2],[3,3,3]],-1)

if __name__ == '__main__':
    main()

更新:我做了很少的代码更改,但这仍然需要你们的一些回顾。 更改的代码:

from itertools import product
from copy import deepcopy

class Node:
    def __init__(self,id):
        self.id = id
        self.dict = {}

    def __str__(self):
        return str(self.id) + " : " + str(self.dict)

    def __repr__(self):
        return str(self.id) + " : " + str(self.dict)

def tryDelete(nodes,_len):
    for i in range(len(nodes)):
        y = nodes[:]
        x = y[i]
        del y[i]
        tNodes = []
        for node in y:
            for input,result in node.dict.items():
                if result == x:
                    node.tDict = deepcopy(node.dict)
                    if x.dict[input] == x.id:
                        node.dict[input] = node
                    else:
                        node.dict[input] = x.dict[input]

        if pathPossible(y,_len ,False) == -1:
            return x.id
        for n in tNodes:
            n.dict = n.tDict
            del n.tDict
    return -2

target = {}
def FindTarget(node,p):
    if len(p) == 1:
        return node.dict[p[0]]
    if node not in target or p not in target[node]:
        x = Gnodes[FindTarget(node,p[:-1])].dict[p[-1]]
        if node not in target:
            target[node] = {}
        target[node][p] = x
    return target[node][p]

def allSatisy(nodes,p):
    x = None
    for node in nodes:
        if x is None:
            x = FindTarget(node,p)
        elif FindTarget(node,p) != x:
            return False
    return True

def allPossiblePaths(l,n):
    #x = int(((l+1)*(l+2))/2)
    for i in range(1, n + 1):
        for p in product(range(l),repeat=i):
            yield p

def pathPossible(nodes,_len ,isItereate=True):
    i = 1
    isFound = False
    for p in allPossiblePaths(_len,len(nodes)):
        if allSatisy(nodes,p):
            isFound = True
            break

    if isFound:
        return -1
    elif not isItereate:
        return -2
    else:
        return tryDelete(nodes,_len)

Gnodes = []
def answer(li):  
    Gnodes[:] = []
    for i in range(len(li)):
        Gnodes.append(Node(i))#[i] = Node(i)
    for i in range(len(li)):
        for j in range(len(li[i])):
            Gnodes[i].dict[j] = li[i][j]
    return pathPossible(Gnodes,len(Gnodes[0].dict))

def check(li,ans):
    x = answer(li)
    print(str(li) + " : " + str(ans) + " : " + str(x))

def main():
    check([[2,1],[2,0],[3,1],[1,0]],-1)
    check([[1,2],[1,1],[2,2]],1)
    check([[1,3,0],[1,0,2],[1,1,2],[3,3,3]],-1)

if __name__ == '__main__':
    main()

有一个很棒的图形库叫做NetworkX。 它涉及创建图形和路径查找。 您可以指定Graph中存在哪些边或路径,并且可以使用大量算法(例如广度优先搜索或A *以及算法部分中的许多其他算法)来查找路径。 优化时间的最佳方法是代码重用。 https://networkx.github.io

暂无
暂无

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

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