染色体包含以不同方式产生的许多分数。 compareTo方法实际测试方法的一致性,并相应地返回结果。
返回1:comp = -5 ..- 1
返回0:comp = 0(可能发生在不同场景中,其中一个是所有得分相等。
返回-1:comp = 1..5
public int compareTo(Chromosome o) {
if(o == null)
return(1);
int comp = 0;
comp += Double.compare(getScore(1),o.getScore(1));
comp += Double.compare(getScore(2),o.getScore(2));
comp += Double.compare(getScore(3),o.getScore(3));
comp += Double.compare(getScore(5),o.getScore(5));
comp += Double.compare(getScore(7),o.getScore(7));
if(comp == 0)
return(0);
if(comp > 0)
return(1);
else
return(-1);
}
我的问题是,如何使这种情况符合comparator合同规定的规则。 显然它没有,我一直得到: java.lang.IllegalArgumentException:比较方法违反了它的一般合同!
答案 0 :(得分:2)
如果你正在实现Comparator接口,那么你需要使用这个方法(假设你的类在Chromosome tpye中是通用的):
int compare(Chromosome o1, Chromosome o2)
但是,在您的情况下,更合适的接口似乎是Comparable。 http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
int compareTo(Chromosome o)
通常可以实现Comparable,以便为您的类的实例提供自然的顺序。比较器通常是您要比较的单独类,可用于为您提供几种不同类型的排序。
无论您正在实施什么,该类也需要输入:
class Chromosome implements Comparable<Chromosome>
否则参数应该是Object,而不是Chromosome。
答案 1 :(得分:1)
详细说明Sir SirN先生的回答:
compareTo
方法应遵循两个属性:
A=B
然后是B=A
,如果是A<B
那么B>A
A<B
和B<C
然后是A<C
,如果是A=B
和B=C
那么A=C
第一个属性符合您的比较,但第二个属性不符合。考虑以下来自投票理论的例子:我们有3个人,他们投票给3个选择。排名最高的替代品获胜。众所周知,这可能导致一种模糊的情况,没有其他选择。
在您的情况下,分数是人,染色体是替代品。我只使用3,而不是5分,因为这足以显示问题。我有3条染色体,A
,B
和C
,分数如下:
A: 1, 2, 3
B: 2, 3, 1
C: 3, 1, 2
不难看出A<B
,B<C
,和 C<A
,因此您的比较不具有传递性。
你可以通过字典顺序排序染色体来解决这个问题:
public int compareTo(Chromosome o) {
if(o == null)
return(1);
int[] indices = {1, 2, 3, 5, 7};
for (int i : indices) {
int c = Double.compare(getScore(i),o.getScore(i));
if (c != 0)
return c;
}
return 0;
}
答案 2 :(得分:0)
Wat尝试实施似乎是一个染色体比另一个更大,如果它的分数大于另一个的分数。不幸的是,这并没有提供明确的优先权。即你无法保证每个o1 = o2和o2 = o3 o1 = o3都是真的。这可能会导致订购无限循环,或者使用更高级的算法来解决您所面临的问题。所以你需要找到另一种算法来提供稳定的排序。
方法是: