目前我正在用Python编写一些图论理论,此时就是DFS。我创建了一个Node类,它包含Node的名称(如果你愿意,它包含顶点)和一个字符串列表,其中包含与之连接的所有其他节点的名称。
# Simplified for the sake of the question.
class Node:
""" Node using an adjacency list to know which other
nodes it's connected to. """
def __init__(self, name, edges):
self.name = name # Letter normally, like C.
self.edges = sorted(edges) # List of letters for Nodes.
self.visited = False
我发现尝试包含一个Node对象列表而不是每个节点名称的字符串是不现实的,因为这将涉及在创建连接节点列表之前确保所有节点都存在。
这意味着当我想查找一个节点做DFS这样的事情时,我需要一个这样的函数:
def getNode(nodeLetter, nodes):
for node in nodes:
if node.name == nodeLetter:
return node
return None
此函数可以取O(| V |)时间,与顶点数成比例。这将随着时间的推移而积累,因为在整个探索中我将需要访问每个顶点,使得总复杂度为O(| V | ^ 2)。如果我使用了字典,例如:
{"A": ["C", "E"], "E", ["A"]}
我可以有恒定的时间查找。这当然会引入一些问题,例如我存储额外属性的地方,如visited
,以及前后数字,以及我可能需要的任何其他内容。
我怎样才能在这里得到最好的两个世界,一个班级的整洁和一个字典的效率。有没有给定键的类的有效词典?热衷于学习如何最好地解决这个问题。
答案 0 :(得分:1)
你可以继承大多数Python类型(除了NoneType,据我所知,还有GeneratorType)。
做这样的事情:
class MyDict(dict):
'''This walks and talks like a dict'''
def do_something(self):
print(repr(self))
您可以随意扩展它,您甚至可以覆盖__getitem__
和__setitem__
魔术方法来控制数据在dict中的访问和存储方式。
在这种情况下,我们可以实例化dict,并充分利用这两个世界:
>>> mydict = MyDict([('a', 3)])
>>> kwd_init = MyDict(a=3)
>>> dict_init = MyDict({'a': 3})
>>> mydict.do_something()
{'a': 3}
在您的特定情况下,只需将其应用于节点架构即可。
class Node(dict):
'''Defines a node object'''
get_node = dict.__getitem__
set_node = dict.__setitem__
现在我们可以扩展它来存储以前访问过的节点,最有可能是使用列表。
class Node(dict):
'''Defines a node object'''
def __init__(self, *args, **kwds):
super(Node, self).__init__(*args, **kwds)
self.visited = []
def __getitem__(self, name):
'''Get the node but also store it as the last visited item'''
value = dict.__getitem__(self, name)
self.visited.append(name)
return value
get_node = __getitem__
set_node = dict.__setitem__
如果要为受访节点提供持续的查找时间,请使用集合。如果您想要两者,请尝试自定义OrderedSet。
不是太难了,是吗?
答案 1 :(得分:0)
为什么你不创建一个将字母链接到节点而不是遍历所有节点的dict,只要你想知道哪个节点有字母。
所以这个想法很简单
def getNode(nodeLetter, nodes):
for node in nodes:
if node.name == nodeLetter:
return node
return None
到这个
def getNode(nodeLetter, nodesandlettersdict):
return nodesandlettersdict(nodeLetter)