首页 > 解决方案 > 找到帕累托边界的具体分治算法的参考实现

问题描述

给定任何部分可排序元素的集合,可以将所述集合的最大值作为不小于集合中任何其他元素的所有元素。当这个集合是一组 n 维向量时会发生一种特殊情况(在 Rust 中,我们可以有类似(D1,D2,D3,...,Dn)n 维向量的类型并且Vec<(D1,D2,D3,...,Dn)>可以是 n 维向量集合的类型),其中每个维度Di是完全有序的,偏序定义为(a1,a2,a3,...,an)<=(b1,b2,b3,...,bn)iff (a1<=b1) && (a2<=b2) && (a3<=b3) && ... && (an<=bn)。在这种情况下,最大值在多个领域中是众所周知的,因为如果维度被解释为要优化的目标,它就是帕累托边界,如果维度被解释为表的列,它就是天际线查询的结果。

Bentley80和其他几篇论文中,描述了一种找到该最大值的有效算法。这是我目前对其外观的理解(所以请阅读原始描述,因为这个描述来自一个实际上并不知道它是如何工作的人!):


参数:向量的集合V:Vec<(D1,D2,D3,...,Dn)> where D1,D2,D3,...,Dn:Ord,按其第一个维度D1和多个n>=3维度排序。

结果:一个集合M恰好具有 的最大值V

脚步:

  1. 如果集合只包含一个向量或者是空的,我们就完成了;M=V. 否则,继续执行步骤 2。
  2. 选择 cross 的中值,并将集合分成两半,其中分量小于中值的V所有向量在 中,其他向量在 中。DnDnV1V2
  3. 递归计算 和 的最大值,V1分别V2得到M1M2
  4. 如果,则沿n == 3迭代,从具有最大分量的向量开始,以最小分量结束。对于本次迭代中的每个向量,如果是 in ,则将其放入,如果它是最大的,则记录其分量。否则,在; 如果它的分量不小于对向量观察到的记录,则将其放入。迭代完成后,我们也完成了;结果是。M_1.append(M_2)D1D1vvM2MD2vM1MD2M1M
  5. 如果n > 3,则递归计算 的最大值M1.append(M2),但将其n - 1作为考虑的最大维度,并跟踪哪些向量在 中,哪些向量在M1M2

不幸的是,我自己无法实现它。所以我问 StackOverflow:有人可以提供一个简单、可理解的算法实现吗?不需要特定的编程语言,实际上伪代码在这种情况下可能是最明确的选择,但我必须要求不要省略细节。在我看来,像 C 或 Rust 这样的系统语言会对此有所帮助。

当然,我自己(在 Rust 中)也尝试过这样做,但有几件事让我感到困惑:

标签: algorithmimplementationdivide-and-conquerpareto-optimality

解决方案


推荐阅读