我有这段代码:
package org.optimization.geneticAlgorithm;
import org.optimization.geneticAlgorithm.selection.Pair;
public abstract class Chromosome implements Comparable<Chromosome> {
public abstract double fitness();
public abstract Pair<Chromosome> crossover(Chromosome parent);
public abstract void mutation();
public int compareTo(Chromosome o) {
int rv = 0;
if (this.fitness() > o.fitness()) {
rv = -1;
} else if (this.fitness() < o.fitness()) {
rv = 1;
}
return rv;
}
}
每次运行此代码时都会出现此错误:
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:835)
at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:453)
at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:376)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:182)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
at org.optimization.geneticAlgorithm.GeneticAlgorithm.nextGeneration(GeneticAlgorithm.java:74)
at org.optimization.geneticAlgorithm.GeneticAlgorithm.execute(GeneticAlgorithm.java:40)
at test.newData.InferenceModel.main(InferenceModel.java:134)
我使用OpenJDK7u3,当对象相等时我返回0。有人可以向我解释这个错误吗?
答案 0 :(得分:9)
如果您有任何NaN值,您可能会遇到这种情况:
例如:
public class Test
{
public static void main(String[] args) {
double a = Double.NaN;
double b = Double.NaN;
double c = 5;
System.out.println(a < b);
System.out.println(a > b);
System.out.println(b < c);
System.out.println(c < b);
}
}
所有打印false
。所以你最终可能会遇到两个非NaN值都被认为与NaN“相等”的情况,但是一个比另一个更大。基本上,您应该弄清楚如何处理NaN值。当然,检查那确实是问题......你真的想要NaN值来适应你的身体吗?
答案 1 :(得分:4)
很可能你的健身功能被打破了,有两种方式:
compareTo()
在NaN存在的情况下不具传递性。您可以使用Double.compare()
重写比较函数:
public int compareTo(Chromosome o) {
return Double.compare(o.fitness(), this.fitness());
}
这需要更少的代码并处理极端情况(NaN,负零等)。当然,这些角落案件是否应该首先出现,由你来决定和解决。
答案 2 :(得分:0)
您应该尝试添加if (this == o) return 0;
因为必须返回相同的对象。