【问题标题】:how to check if the attribute of an instance is member of a queue in O(1)?如何检查实例的属性是否是 O(1) 中队列的成员?
【发布时间】:2017-09-30 17:53:48
【问题描述】:

我正在尝试使用 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 方法将属性状态作为字符串类型来查看是否包含在具有成员的所有字符串状态的集合中。但这仍然很慢。

那么有可能检查一个实例是否具有另一个实例的相同属性而其他属性可能不同? 例如,两个节点,相同的状态属性但不同的父属性。

如何在不使用额外探索集的情况下保持元素的顺序并在 O(1) 中仍然检查队列中是否有某个元素?

【问题讨论】:

  • 不太清楚你在问什么。您想避免在队列中出现两次相同的状态吗?或者解决当队列中可能有第二个具有相同状态的节点时从集合中删除弹出状态的问题?
  • 我想避免在队列中合并具有相同状态的节点。我编辑问题以澄清这部分。
  • 您希望添加现有状态的尝试大声失败还是被忽略?
  • 在该状态存在的情况下使用属性check_member时返回False

标签: python queue priority-queue


【解决方案1】:

您需要一个 set/dict 类型的对象来实现O(1) contains-check 复杂性。最简单的方法是使用OrderedDict 作为底层数据容器。使用状态作为键,节点作为值。这样,状态被强制为唯一,并且仍然保持顺序:

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

【讨论】:

  • 我不认为你可以在 O(1) 中使用 set type 检查元素是否存在
  • @Harry 不太确定我是否理解你。首先,我的解决方案不使用set。其次,set 正是为此目的而设计的:高效地存储和检索有关元素存在的信息。
  • "你需要一个 set/dict 类型的对象来实现 O(1)"。我认为您无法使用 set 类型实现 O(1) 。因为在集合中找到一个对象是 O(n)
  • @Harry。不,这不对。在所有元素都具有相同哈希值的最坏情况下,它可能是。但对于任意数据,摊销成本为O(1)wiki.python.org/moin/TimeComplexity#set
  • wiki.python.org/moin/TimeComplexity 对于集合类型,x 在 s 中的最差时间复杂度是 O(n)。我不是在陈述你的回答,而是陈述。所以你可以编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多