具有infima的部分排序优先级的优先级队列


16

我有一些优先级为复合类型的对象,并且仅部分排序。我需要按此优先级顺序选择对象(即每次产生最少的项)。但是,我宁愿选择队列是否稳定(从某种意义上说,如果存在多个最小元素,则应该首先返回最旧的元素),而不是随意完成订单。

是否有任何可用于部分排序的堆数据结构?还是修改了常规优先级队列才能使用它?我需要的算法的常见选择是简单的二进制或四进制堆,但这不适用于部分排序。

优先级值支持:

  1. 一个b b 一个abba也可能为假。在这种情况下,我写。a⋚̸b
  2. 查找INFI(glb)和uprema(lub)。是最大y,因此y \ preccurlyeq x_i。计算n个值的最小值需要O(n)时间。ý ý X Ñ ø Ñ inf(xi)yyxinO(n)下确界(并确)每一组的存在。
  3. 可以定义部分排序的线性扩展。将其用于优先级队列是一种简便的方法,因为该算法确实可以正常工作。但是顺序会影响性能,插入顺序看起来应该最好,以避免最坏的情况。

另外,我要在其中使用的算法需要知道队列中所有优先级的最小值。

优先级具有现实意义,但可能会发生变化,因此依靠它们可能拥有的其他属性似乎并不可行。


注意:二进制堆不适用于部分排序。假设一个带有abc的二进制堆c,其中aca⋚̸b以及a⋚̸c。它们按该顺序放置,所以

     a (0)
   /   \
 b (1)   c (2)

现在已插入d。下一个自由头寸是3,b的左孩子b,所以我们得到

        a (0)
      /   \
    b (1)   c (2)
  /
d (3)

如果(从传递性中暗示,但未和)和,则不会与交换,因为它不少于。但它实际上是小于d ç d b d ̸ b d b dadcdbd⋚̸bdba,但是没有与它进行比较,因此现在主堆不变式不再成立。顶部不是最小的。

我怀疑可以使二项式堆样式的堆森林起作用。基本上,始终将新值与root进行比较并且仅将可比较的元素链接在一起非常重要。这将使森林中的树木具有随机大小,从而使复杂度取决于堆中相互不可比拟的集合的数量。我有点怀疑复杂性无法解决(我们必须继续比较直到找到可比较的元素)我可能错过了一些东西,因此我将其保留下来。


注意:排序是局部的,虽然有多种方法可以为其定义线性扩展,但添加时间戳并将其用作辅助标准并不是其中一种。假设我们分配的时间戳为每个和定义的排序作为当且仅当或(和。然后假设我们有不同的,,,使得和。然后t(a)aababbat(a)t(b)abct(a)t(b)t(c)caabbc,但是,因此该关系不是可传递的,因此根本不是有序的。这种扩展仅适用于弱排序,而不适用于部分排序。ca


编辑:我意识到不仅定义了任何集合,而且我实际上需要能够有效地获取队列中当前的元素。因此,我现在正在考虑将包含子树信息的特殊节点添加到某些常见堆结构是否有帮助。


您是否考虑过索引优先队列?

@hulkmeister:您能否解释一下如何对索引建立索引使它可以用于部分排序(不,普通二进制堆不能用于部分排序)?

1
我的想法是,当两个项目无法比拟时,您可以使用索引来跟踪插入的顺序。因此,将优先级与索引组成,即使没有优先级,您也具有可比的唯一键。如果这听起来像您想要的,我可以将其提供完整的答案。

1
@hulkmeister:嗯,问题远不止于此。插入新项目时,优先级队列通常会将其与某个元素进行比较。但是,如果它们无与伦比,它根本不知道在哪里插入。而且,对索引进行歧义化是行不通的,因为索引会发生变化,并且因为索引可能始终无法给出与优先级一致的总排序。

您能举一个这种复合类型的例子吗?是否可以认为这些“无可比拟”的值相等?如果是这样,则可以按插入顺序将它们存储在同一节点中。

Answers:


3

尽管原始问题中提出的确切问题似乎确实很困难(并且我会对解决该问题感兴趣,特别是在发现图像的部分中感兴趣)。我只想指出,如果部分排序的集合确实由使用乘积订单的向量组成,并且只要保证优先级队列以与部分订单“兼容”的顺序返回值就足够了(也就是说,总是在较小的元素之前返回较小的元素),然后有一种相当简单的方法。

这个想法实质上是找到部分有序集的拓扑排序。也就是说,总订单“ ”,使得一个bT。对于使用产品订单矢量,这是相当容易的:只使用一个词典编纂顺序“小号 ”,其中所述第一“部件”是所有用于产品订单的组分的总和(各组分的其余部分基本上是任意的,因此您也可以坚持执行弱订单)。然后我们可以看到 a < babaTbS一个 = b

a<bi(aibi) and i(ai<bi)(iai)<(ibi)aSb
并且因此一个b
a=bi(ai=bi)(iai)=(ibi)aSb,
。因此,我们可以将此顺序与优先级队列一起使用,并确保较小的元素(按产品顺序)将始终在较大的元素之前被提取。abaSb

还有更多选择。使用分量之一,最小值,最大值,至少具有非负系数的任何线性组合。扩展名的选择会影响覆盖算法的速度。
2013年

2

完成部分订购有什么问题?

但是,我宁愿选择队列是否稳定(从某种意义上说,如果存在多个最小元素,则应该首先返回最旧的元素),而不是随意完成订单。

如果您更喜欢“最早的”,那么您的订单就可以有效地完成;“无与伦比”的物品在年龄上是可比的。

为每个项目添加一个时间戳(或任何其他单调增长的整数),如果不可能进行“真实”比较,则可以使用它。


3
如果可以对部分排序进行线性扩展,那就太好了。但事实并非如此。让我们有3个不同的值,以abc的顺序插入,使得c≤ab与任何一个都不可比。带时间戳的扩展填充了a≤'bb≤'c,因此从传递性开始,a应该小于c,但这与实际的顺序相矛盾。

也许您将其与较弱的排序混淆了。在弱序中,不可比元素形成等效类,因此您可以添加任意其他条件。对于部分订购,您不能。

1

编辑:这似乎是一个有趣的问题,对此我进行了一些研究。我建议您阅读以下内容:

  1. 达瑞尔·雷蒙德(Darell Raymond)。滑铁卢大学博士学位论文部分订购数据库。

我建议您阅读以下文章:Daskalakis,Constantinos等。“在坐姿中进行排序和选择。” SIAM计算杂志40.3(2011):597-622。

作者在这里提出了一个称为ChainMerge的数据结构,该结构接受一个位图和该位图分解成条链的链。的数据结构的大小是Ô Ñ q 。作者提出了一种算法,用于找到在O w n 中运行的极小值,其中w是摆幅宽度的上限。..我认为也许这很有趣。qO(nq)O(wn)w

注意:我删除了以前的幼稚答案。请单击编辑以查看它。


0

我使用的术语可能不正确。请直接编辑我的答案以解决您发现的任何问题。


首先,需要从输入中检测到互不相同的集合。

例如,可能有5个对象a, b, c, d, e,但它们的部分排序形成了两个断开的图:

  • a ≤ b ≤ c
  • d ≤ e
  • 但任何一个{a, b, c}都无法与之相比{d, e}

在将对象存储到适当的数据结构中之前,首先需要检测这些互不相同的集合。这可以通过联合查找算法完成


为了提高效率,插入新对象需要有一种有效的方法来查找“与该新对象相当的现有对象列表”。


现在,在每个子集中(分别为{a, b, c}{d, e})内,最小值应被明确定义。(对于每个子集,可以有一个或多个 minima, due to partial ordering.)

I see this as a directed acyclic graph. Trying to fit it into a heap seems disastrous.


To extract the minima from this composite data structure, the next step is to get the list of all minima from all subsets, pick the one with the earliest timestamp, and remove and return this object.


Unfortunately I don't see way to efficiently find the list of comparable objects.

Partially ordered set can indeed be viewed as directed acyclic graph. But one given by adjacency table (function, actually) rather than adjacency list. Finding minima of poset given by adjacency list is easy, but for adjacency table it's a problem.

Minima are well-defined in the original set as well. I don't see how finding the connected components could help, since they are not complete graphs.

1
您似乎假设Hasse图是一元树的森林(等效为路径图),但是问题已经说明它是产品订单,因此是多维晶格。
彼得·泰勒

0

我正在从事的项目涉及类似的问题(顺便说一句,我也在使用矢量的偏序)。我们已经有了用于排序随机排序列表的二次时间算法,并且我通过观察只有一个对象出现故障时的行为来开发一种插入算法。我们不知道这是否是最快的实现。

这是一些伪代码。

class PartialOrderPriorityQueue
   q <- empty list
   method insert (n):
     for i <- 0 to (q.length - 1):
       if q[i] <= n:
         t <- q[i]
         q[i] <- n
         n <- t
     q.append(n)

   method pop():
     return q.remove(0)

-1

通常的堆行为是将新值附加到后面,然后在其比父级更大时进行筛选。

如果您编写的比较结果对于父级和子级没有可比的情况返回相同,因为对于父级大于子级,则筛选应该仍然在正确的点终止。

就您的目的而言,这是否算是足够稳定的订购?


为了阐明这一点,请从您的注释中举一个例子:a> b,并且cab不具有可比性:

  • a然后b然后c => a,b,c ...这已经是堆顺序了,没有任何东西在筛分
  • b,a,c => a,b,c ... a被筛选到正确的位置,再次我们按照正确的堆顺序
  • a, c, b => a, c, b ... b can't sift up because it is not comparable with c, but this leaves them in FIFO order as you asked
  • c, b, a => c, a, b ... a and b are in the correct relative order, but neither can get ahead of c because they can't be compared with it

so, the result depends on the order of insertion - this seems to match what you ask for, but I'm not sure whether it's really what you want. If it isn't, could you show the result you hoped to see?


好的,因此从您的评论(和对问题的编辑)中,您确实希望“可比较”元素跳过“不可比较”元素,并在顺序下找到正确的位置(如果有)。我问这个是因为我不确定如何解释

如果某些元素无法比拟,则会按插入顺序返回它们

(d和b在编辑中是成对的,但您希望它们按插入的顺序排列)。

我的下一个问题是“可比较”和“不可比较”元素之间的关系,但是我看到您现在已经揭示它们是产品顺序中的向量(尚不清楚某些元素是否成对出现,无法与任何事物(例如NaN或其他)相比。

因此,如果我采用您的新示例并分配矢量值,那么这是b与其他任何事物都不可比的示例是否正确:

        a (1,1)
      /      \
    b (0,4)   c (3,3)
  /
d (2,2)

它应该排序为:

        a (1,1)
      /      \
    d (2,2)   c (3,3)
  /
b (0,4)


I explicitly mentioned in the question that it won't work, because I thought I have a counter-example, but I am not so sure with it now. Can you prove that such queue would be sound (for deletemin, insert and update too)? And remember, that it's possible that a ≤ b, but c is not comparable (and would therefore compare "equal" with the above rule) to either of them.

好吧,这还不能证明。不必关心顺序,并证明此类堆始终在顶部具有最小的元素(请注意:(更多)通用约定,并且对算法的实际需要在顶部最小),因此,如果a> bb首先出现)。

其实我怀疑有反例。假设abc在堆中,a≤ba≤ca是顶部,b是左孩子,c是右孩子。现在d谈到的是d≤Ç和无与伦比的与一个b。它作为b的子元素插入,不少于并停留在那里。现在出现了e,它等于c≤e(因此也等于a≤e),与b不可比。因此,E作为b的正确子进入和留下来。现在提取一个 (OK, a is minimal), e gets swapped in it's place and sifted down. It is incomparable to b, but less than c, so swaps with c. Now extract c, WRONG, d ≤ c.

If you find a mistake in the previous comment (which would need to have a form of inequality that has to hold because of transitivity and I missed it), you'd still have a chance. Otherwise it won't work.

1
Ok, even simpler counter-example. Suppose a, b and c are in the heap, a ≤ c, b is incomparable with either. a is top, b is left child, c is right child. d comes in so that d ≤ a (thus d ≤ c) and incomparable with b. Next free slot is as left child of b and d is incomparable, so it stays there. Now extract a, WRONG, d ≤ a. Note that whether a ≤ c or not does not matter, the situation is the same if they were incomparable.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.