我尝试使用python 3.6设计队列数据结构
队列的目标是使用这些属性跟踪节点对象:
class node(object):
def __init__(self, state, parent):
self.state = state
self.parent = parent
我希望避免在队列中合并具有相同状态的节点。所以我设计了以下队列:
class queue(object):
def __init__(self):
self.list = []
self.explored = set()
def insert(self, element):
self.list = [element] + self.list
self.explored.add(str(element.state))
return self.list
def pop(self):
oldest_element = self.list.pop()
self.explored.remove(str(oldest_element.state))
return oldest_element
def empty(self):
return len(self.list) == 0
def check_member(self, other):
return other in self.explored
为了检查节点的状态是否在队列中,我使用check_member
方法将属性state作为字符串类型,以查看是否包含在集合中的所有字符串状态成员。但这仍然很慢。
因此可以检查实例是否具有与其他属性不同的另一个实例的相同属性? 例如,两个节点,相同的状态属性但不同的父属性。
如何在不使用额外探索集的情况下保持元素的顺序并仍然检查某个元素是否在O(1)的队列中?
答案 0 :(得分:2)
您需要set / dict类型对象来实现O(1)
包含检查复杂性。最简单的方法是使用OrderedDict
作为基础数据容器。使用state作为键,使用节点作为值。这样,强制执行的状态是独一无二的,并且仍然保持订单:
from collections import OrderedDict
class queue(object):
def __init__(self):
self.q = OrderedDict()
def insert(self, element):
s = str(element.state)
if s not in self.q:
self.q[s] = element # adds to the end
def pop(self):
return self.q.popitem(0)[1] # returns the node from beginning
def empty(self):
return not self.q
def check_member(self, element):
return str(element.state) in self.q
答案 1 :(得分:-1)
您可以通过仅添加对象本身而不是在可能的情况下调用其状态来节省时间,但至少不调用str()可以将时间缩短一半。这似乎没必要。
>>> setup="""class Obj(object):
... def __init__(self):
... self.str = "str"
...
... tst_ob = Obj()
...
... container = list()"""
>>>
>>> test="""container.append(tst_ob.str)"""
>>>
>>> from timeit import timeit
>>>
>>> timeit(test, setup=setup)
0.16077090999988286
>>> setup="""class Obj(object):
... def __init__(self):
... self.str = "str"
...
... tst_ob = Obj()
...
... container = set()"""
>>>
>>> test="""container.add(str(tst_ob.str))"""
>>>
>>> from timeit import timeit
>>>
>>> timeit(test, setup=setup)
0.29905145599991556