查找部分有序集的最大元素的高效算法

时间:2014-02-04 18:38:20

标签: algorithm poset

我有一个部分有序的集合,比如说A = [x1, x2, ...],意味着对于集合中的每个xixj,(确切地说)四种可能性中的一种是真的:{{1} },xi < xjxi == xjxi > xjxi是无法比拟的。

我想找到最大元素(即没有元素xjxi的元素xj)。什么是有效的算法(最小化比较次数)?我尝试构建DAG并进行拓扑排序,但只是构建图形需要O(n ^ 2)比较,这太多了。

我在Python中这样做,但如果你不知道,我可以阅读其他语言或伪代码。

4 个答案:

答案 0 :(得分:6)

无论你做什么,似乎最坏的情况是O(n ^ 2)。例如,如果没有可比较的元素,那么您需要将每个元素与每个其他元素进行比较,以确定它们都是最大的。

如果你允许O(n ^ 2),因为排序是可传递的,你可以只通过集合进行一次传递,保留到目前为止最大的所有元素的列表;每个新元素都会淘汰任何&lt;它会被添加到最大列表中,如果它不是&lt;任何最大元素。

答案 1 :(得分:3)

在最坏的情况下,你不能比O(n ^ 2)快。实际上要检查所有元素对于没有元素可比较的poset的最大值,您需要比较每对元素。所以在最坏的情况下它绝对是二次方的。

答案 2 :(得分:2)

假设您已经查看了所有(n选择2)比较,除了一个,在x i 和x j 之间,i!= j。在某些情况下,只有两个最大候选者才是这两个,x i 和x j

如果你不比较x i 和x j ,你就无法明确地说出它们是否都是最大的,或者是否只有其中一个是。

因此,您必须检查所有可能的(n选择2)(O(n 2 ))比较。


请注意,这假设您的部分有序集使用黑框进行指定,以进行比较。如果部分有序集合以图表的形式给出,您可以随后在子O(n 2 )时间内找到最大元素集合。

答案 3 :(得分:1)

正如其他答案所指出的,最坏的情况复杂性是O(n ^ 2)。

然而,有一些启发式方法可以在实践中提供很多帮助。例如,如果集合A是Z ^ 2(整数对)的子集,那么我们可以预先消除很多点:

  1. 沿x轴排序(对于给定的x值,例如1,找到点 使用最大y值,重复所有x值)以获得候选集 最大,称之为y-maximals。
  2. 同样获取set x-maximals。
  3. 相交以获得最终候选集xy-maximals。
  4. 这是成本O(n)。很容易看出任何最大点都将出现在xy-maximals中。但是,它可以包含非最大点。例如,考虑集合{(1,0),(0,1),(2,2)}。

    根据您的情况,这可能是一个足够好的启发式方法。您可以在较小的集合xy-maximals上使用详尽的算法进行跟进。

    更一般地说,这个问题被称为'Pareto Frontier'计算问题。以下是很好的参考资料:

    http://www.cs.yorku.ca/~jarek/papers/vldbj06/lessII.pdf

    https://en.wikipedia.org/wiki/Pareto_efficiency#Use_in_engineering_and_economics

    特别是第一个参考文献中的BEST算法非常有用。