部分有序比较器

2022-09-04 02:12:23

如何实现根据偏序关系对其元素进行排序?java.util.Comparator

例如,给定一个偏序关系 acbc;ab 的顺序未定义。

由于需要完全排序,因此实现对部分排序未任意定义但一致的元素进行排序。Comparator

以下方法是否有效?

interface Item {
    boolean before(Item other);
}

class ItemPartialOrderComperator implements Comparator<Item> {
    @Override
    public int compare(Item o1, Item o2) {
        if(o1.equals(o2)) {  // Comparator returns 0 if and only if o1 and o2 are equal;
            return 0;
        }
        if(o1.before(o2)) {
            return -1;
        }
        if(o2.before(o1)) {
            return +1;
        }
        return o1.hashCode() - o2.hashCode(); // Arbitrary order on hashcode
    }
}
  • 此比较器的排序是否可传递?
    (恐怕不是)
  • 是否需要可传递?
    (在树状图中使用时)Comparators
  • 如何正确实现它?
    (如果上面的实现不起作用)
    (哈希码可以碰撞,为简单起见,该示例会忽略碰撞;请参阅Damien B对Java中*any*类的所有实例施加总排序的答案,以便对哈希码进行故障安全排序。

答案 1

问题是,当你有无与伦比的元素时,你需要回退到比比较哈希代码更聪明的东西。例如,给定一个偏序 {a < b, c < d},哈希代码可以满足 h(d) < h(b) < h(c) < h(a),这意味着 a < b < c < d < a(粗体表示被哈希代码破坏的领带),这将导致 a 的问题。TreeMap

一般来说,除了事先对键进行拓扑排序之外,您可能没有什么可做的,因此欢迎您提供有关您感兴趣的偏序的一些详细信息。


答案 2

它似乎更像是一个答案而不是评论,所以我会发布它

文档说:

从比较的合约中可以立即得出,商是S上的等价关系,并且强加的排序是S上的总顺序。

所以不,比较器需要完全排序。如果您通过部分排序来实现这一点,则违反了接口协定。

即使它在某些情况下可能有效,您也不应尝试以违反接口合同的方式解决问题。

请参阅有关符合部分排序的数据结构的问题。