Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial ordered Comparator

How to implement java.util.Comparator that orders its elements according to a partial order relation?

For example given a partial order relation ac, bc; the order of a and b is undefined.

Since Comparator requires a total ordering, the implementation orders elements for which the partial ordering is undefined arbitrarily but consistent.

Would the following work?

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
    }
}
  • Is this comparator's ordering transitive?
    (I fear that it is not)
  • Are Comparators required to be transitive?
    (when used in a TreeMap)
  • How to implement it correctly?
    (if the implementation above doesn't work)
    (Hashcodes can collide, for simplicity collisions the example ignores collisions; see Damien B's answer to Impose a total ordering on all instances of *any* class in Java for a fail-safe ordering on hashcodes.)
like image 692
Kasper van den Berg Avatar asked May 22 '13 14:05

Kasper van den Berg


People also ask

What is partial ordering give an example?

A partial order is “partial” because there can be two elements with no relation between them. For example, in the “divides” partial order on f1; 2; : : : ; 12g, there is no relation between 3 and 5 (since neither divides the other). In general, we say that two elements a and b are incomparable if neither a b nor b a.

What is partial ordering relation?

A partial order relation is a homogeneous relation that is transitive and antisymmetric. There are two common sub-definitions for a partial order relation, for reflexive and irreflexive partial order relations, also called "non-strict" and "strict" respectively.

How do you find partial order relations?

A relation R on a set A is called a partial order relation if it satisfies the following three properties: Relation R is Reflexive, i.e. aRa ∀ a∈A. Relation R is Antisymmetric, i.e., aRb and bRa ⟹ a = b. Relation R is transitive, i.e., aRb and bRc ⟹ aRc.

What is total order and partial order?

This definition says that in a total order any two things are comparable. Wheras in a partial order a thing needs neither to be "smaller" than an other nor the other way around, in a total order each thing is either "smaller" than an other or the other way around.


2 Answers

The problem is that, when you have incomparable elements, you need to fall back to something cleverer than comparing hash codes. For example, given a partial order {a < b, c < d}, the hash codes could satisfy h(d) < h(b) < h(c) < h(a), which means that a < b < c < d < a (bold denotes tie broken by hash code), which will cause problems with a TreeMap.

In general, there's probably nothing for you to do except topologically sort the keys beforehand, so some details about the partial orders of interest to you would be welcome.

like image 82
David Eisenstat Avatar answered Oct 07 '22 00:10

David Eisenstat


It seems to be more of an answer than a comment so I'll post it

The documentation says:

It follows immediately from the contract for compare that the quotient is an equivalence relation on S, and that the imposed ordering is a total order on S."

So no, a Comparator requires a total ordering. If you implement this with a partial ordering you're breaching the interface contract.

Even if it might work in some scenario, you should not attempt to solve your problem in a way that breaches the contract of the interface.

See this question about data structures that do fit a partial ordering.

like image 28
Benjamin Gruenbaum Avatar answered Oct 07 '22 00:10

Benjamin Gruenbaum