如何提高此python代码的性能?
我正在解决一个难题(发现给定的自动机是否存在输入,无论其起始状态是什么,每次的最终状态都是相同的),并编写了以下python代码。代码中有一些测试用例是用check方法编写的。对于这些情况,程序运行得相当快。然而,对于存在50个列表(节点)的测试用例,程序的执行将花费很长时间。我正在存储中间结果,以便进一步使用。有没有人能回顾一下代码,并就如何提高代码的性能提出建议如何提高此python代码的性能?,python,python-3.x,optimization,Python,Python 3.x,Optimization,我正在解决一个难题(发现给定的自动机是否存在输入,无论其起始状态是什么,每次的最终状态都是相同的),并编写了以下python代码。代码中有一些测试用例是用check方法编写的。对于这些情况,程序运行得相当快。然而,对于存在50个列表(节点)的测试用例,程序的执行将花费很长时间。我正在存储中间结果,以便进一步使用。有没有人能回顾一下代码,并就如何提高代码的性能提出建议 from itertools import product from copy import deepcopy class No
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。它处理创建图和路径查找。您可以指定图形中存在哪些边或路径,并且可以使用大量算法(如广度优先搜索或a*)以及图形中的许多其他算法来查找路径。优化时间的最佳方法是代码重用。
这可能更合适,因为只要(A)代码有效(B)代码不是假设的或未完成的,代码在
main
方法中针对给定测试用例有效,并且代码也已完成,代码审查就可以接受。我只需要一些关于如何改进代码的建议。您是否对代码进行了分析,以查看代码在哪里被卡住了?一旦完成了,请返回我们。顺便说一句。如果是关于速度的话,Python特别是Python3.x可能是错误的工具。