请在此处查看完整的工作目录:https://github.com/sharpvik/python-libs/tree/alpha/Testing
所以我正在研究Python中的一些Graph理论和编码。我创建了一个名为Graph的类,如下所示(不要担心缩进,在文件本身中它很好):
class Graph: # undirected graph; no values for the edges;
def __init__(self):
self.nodes_counter = 0
self.nodes_dict = dict()
def node_add(self, name): # name(int / str) -- name of the node;
self.nodes_dict.update( { name : list() } )
self.nodes_counter += 1
return name
def node_del(self, name): # name(int / str) -- name of the node;
self.nodes_dict.pop(name, None)
for each in self.nodes_dict:
self.nodes_dict[each].remove(name)
self.nodes_counter -= 1
return name
def connection_add(self, one, two): # one(int / str) and two(int / str) -- two nodes you want to connect;
self.nodes_dict[one].append(two)
self.nodes_dict[two].append(one)
return [one, two]
def connection_del(self, one, two): # one(int / str) and two(int / str) -- two nodes you want to disconnect;
self.nodes_dict[one].remove(two)
self.nodes_dict[two].remove(one)
return [one, two]
def nodes_count(self): # --> function returns the number of nodes in the graph;
return self.nodes_counter
def nodes_return(self): # --> function returns the whole dict containing nodes and their connections;
return self.nodes_dict
def node_return(self, name): # name(int / str) -- name of the node you're checking;
# --> function returns connections of the given node;
return self.nodes_dict[name]
# search
## --> breadth first search using class Queue
def bfs( self, final, queue=Queue(None), checked=list() ): # final(int / str) -- name of the node you're trying to establish connection with;
# queue(class Queue) -- Queue containing the element you are beginning with (format: element);
# checked(list) -- leave empty *** internal use ***;
# --> function returns True if the two nodes are connected, otherwise it returns False;
if queue.length() == 0:
return False
temp = queue.pop()
if temp == final:
return True
else:
checked.append(temp)
for child in self.node_return(temp):
if child not in checked:
queue.ins(child)
return self.bfs(final, queue, checked)
## breadth first search using class Queue <--
## --> depth first serach using class Stack
def dfs( self, final, stack=Stack(None), checked=list() ): # final(int / str) -- name of the node you're trying to establish connection with;
# stack(class Stack) -- Stack containing the element you are beginning with (format: element);
# checked(list) -- leave empty *** internal use ***;
# --> function returns True if the two nodes are connected, otherwise it returns False;
if stack.length() == 0:
return False
temp = stack.pop()
if temp == final:
return True
else:
checked.append(temp)
for child in self.node_return(temp):
if child not in checked:
stack.add(child)
return self.dfs(final, stack, checked)
## depth first serach using class Stack <--
最后bfs
和dfs
函数依赖于我的其他两个类:
class Stack:
def __init__(self, element):
if isinstance(element, list):
self.storage = element
else:
self.storage = [element]
def add(self, element):
self.storage.append(element)
return element
def pop(self):
temp = self.storage[-1]
self.storage.pop(-1)
return temp
def length(self):
return len(self.storage)
和
class Queue:
def __init__(self, element):
if isinstance(element, list):
self.storage = element
else:
self.storage = [element]
def ins(self, element):
self.storage.insert(0, element)
return element
def pop(self):
temp = self.storage[0]
self.storage.pop(0)
return temp
def length(self):
return len(self.storage)
现在,在另一个文件中,我已初始化了一个新的Graph
,我将其调用g
进行简单测试并对其进行测试。
print("BFS for 1 and 2 # --> should return True")
print( g.bfs(2, Queue(1) ), end="\n\n" )
print("BFS for 1 and 4 # --> should return True") # but returns False!!!
print( g.bfs(4, Queue(1) ), end="\n\n" )
现在,当我开始调试它时,我注意到由于某种原因跟踪已检查节点的checked
列表仍然充满了第一次调用该函数所检查的节点,即使我在checked=list()
声明中隐式将其设置为def bfs(...)
,以便每次有人调用该函数时它都为空。这种不寻常的行为导致它不检查节点4,因为它认为它已被检查(checked = [1, 3, 4]
),因此第二次函数决定两个节点没有连接并返回False。
如果我在[]
之后传递Queue(1)
空列表,则可以解决此问题:
print( g.bfs(4, Queue(1), [] ) )
然而,这会使事情变得复杂,我也只是想知道为什么它会这样做。所以,如果有人知道这里到底发生了什么,我期待着你的回应。