I'm afraid that the Java 7 sort implementation will not tolerate a Comparator that exhibits intransitivity. There is nothing you can do about that ... if you want to use the standard Java SE sorting APIs.
But, in fact, using threshold comparison in a sort is actually mathematically incorrect.
The issues when comparing floating point values are that they are often imprecise to start with, and the calculations then typically introduce further small errors into the results. When two results are close enough, the accumulated error may larger than the difference between the values ... meaning that we can't tell whether the ideal numbers (without the errors) are less, equal or greater than each error. We deal with this by treating "close to equals" as being "equal", by comparing using a threshold.
When we are sorting values (i.e. placing them in order), the issue of errors in the values needs to be handled differently. Suppose that
we have two numbers
v1 ± e1
andv2 ± e2
, andwhen we compare the numbers using threshold comparison, the threshold is greater than
mod(e1) + mod(e2)
If it turns out that v1
and v2
are close enough that mod(v1 - v2) < (mod(e1) + mod(e2))
then it doesn't matter if we put v1 ± e1
before or after v2 ± e2
in the ordering. If we observe the ordering of the two numbers (after the sort has completed) by comparing using the threshold, they will show as "equal", which ever order we put them in.
So if we ignored errors and simply ordered the numbers using precise comparisons, we won't put any pair of numbers in an incorrect order as far as we can discern when we use threshold-based comparison.
Now suppose that we have v1 ± e1
, v2 ± e2
and v3 ± e3
... and
mod(e1) + mod(e3)
is GREATER that our threshold:
If we order as above (using precise comparison) we will still end up with the numbers in the right order.
If we used "comparison with thresholds" to order the values (and the sort implementation allowed that!), we could end up with the numbers in the order
v3 ± e3
,v2 ± e2
andv1 ± e1
. We have{v1 ± e1, v2 ± e2}
and{v2 ± e2, v3 ± e3}
are pairwise equal, but we could also have{v1 ± e3, v3 ± e3}
incorrectly ordered, even when we compare using threshold-based comparisons!
The bottom line is that you should simply implement your Comparator
(for sorting purposes!) to use exact comparisons. Threshold comparison is wrong for this context. This applies irrespective of how the sort
algorithm is coded ...