我已经实现了一个深度优先搜索算法,并使用一个名为“call-count”的示例变量,我试图跟踪代码内部执行了多少次递归/比较,即“searchDFS”运行了多少次。在“searchDFS”内部,call_count变量默认为第一次运行searchDFS时的示例变量,然后它被传递到每个递归中,所有其他的示例变量都工作正常,我可以很好地附加到顶级示例数组“final_path”,但是它拒绝递增call_count。
我做错了什么,还有更好的方法吗?
代码:
class Node:
def __init__(self, id, connections):
self.id = id
self.connections = connections
class DFS:
def __init__(self):
self.visited = {}
self.nodes = []
self.final_path = []
self.call_count = 0
def searchDFS(self, nodes, target, current, call_count=None, final_path=None, visited=None):
if(visited == None): visited = self.visited
if(final_path == None): final_path = self.final_path
if(call_count == None): call_count = self.call_count
call_count +=1 # <<< to increment every time searchDFS is ran
if current in visited.keys():
print(f'already visited node {current}')
return 0
else:
print(f'current -> {current}')
visited[current] = 1
if(current == target):
print('found!')
final_path.append(current)
return True
if(nodes[current].connections):
for node in nodes[current].connections:
if(self.searchDFS(nodes, target, node.id, call_count, final_path, visited)):
final_path.append(current)
if(current == 0):
print(final_path[::-1])
print(f'call count: {call_count}') # not incrementing !!! :(
return True
return False
def setup_graph(self):
for x in range(0, 5):
self.nodes.append(Node(x, []))
self.nodes[0].connections = [self.nodes[1], self.nodes[2]]
self.nodes[1].connections = [self.nodes[0], self.nodes[3]]
self.nodes[2].connections = [self.nodes[0], self.nodes[4]]
self.nodes[3].connections = [self.nodes[1]]
self.nodes[4].connections = [self.nodes[2]]
def print_graph(self):
for node in self.nodes:
print(f"node id: {node.id}")
print("children: ")
for childs in node.connections:
print(childs.id)
def main(self):
print('main() init')
self.setup_graph()
self.print_graph()
self.searchDFS(self.nodes, 4, 0)
if __name__ == "__main__":
DFS().main()
1条答案
按热度按时间xt0899hw1#
通过@slothrop(in-depth explanation)解决
区别在于“重新绑定名称”与“改变值”
原语在Python中是不可变的--它们不能被改变,只能创建新的原语(并且变量名被重新绑定到新值):
上面的代码用新值6创建了一个新的内存块,然后x重新绑定到这个新值,这类似于C中指针的工作方式。
未赋值的值会被Python的垃圾收集器自动丢弃。保存“5”的内存单元将被清除,因为它不再被赋值给任何变量。
赋值语句从不复制数据,所以将一个变量赋值给另一个变量不会复制第一个变量,它只是给它“指示”去哪里找值。
“y”仍然“绑定/查看”原始的“5”。还有可变值,如Lists。Lists包含一个内置函数,可以附加到自身。
因为List是一个类,所以它可以有方法来原地改变,而不必像原语那样创建一个全新的值。
在我的代码中,当我赋值“call_count =self.call_count”时,我只将“call_count”的值指向示例变量“self.call_count”的相同值。递增“call_count”只会为 * 本地变量 *“call_count”赋值一个新值,而不会重新赋值原始的 * 示例变量 *“self.call_count”。要解决此问题,我只是创建了一个函数来更新示例的值,并在搜索函数中将一个变量绑定到该方法:
由于
inc
只绑定到一个函数一次,因此inc
的“值”永远不会改变,使用它只会运行同一个函数,该函数将原始示例的变量重新绑定到新值。