3

染色体には、さまざまな方法で生成された多数のスコアが含まれています。compareTo メソッドは実際にメソッドの一致をテストし、それに応じて結果を返します。

リターン 1: コンプ = -5..-1

return 0: comp = 0 (さまざまなシナリオで発生する可能性があり、そのうちの 1 つはすべてのスコアが等しい場合です。

-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);
}

私の質問は、このシナリオをコンパレータの契約によって課された規則に準拠させる方法です。どうやらそうではなく、私は取得し続けます: java.lang.IllegalArgumentException: 比較メソッドが一般契約に違反しています!

4

3 に答える 3

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 は通常、クラスのインスタンスに自然な順序を与えるために実装されます。Comparator は通常、比較しようとしているものとは別のクラスであり、いくつかの異なる種類の順序付けを行うために使用できます。

実装するものに関係なく、クラスも入力する必要があります。

class Chromosome implements Comparable<Chromosome> 

それ以外の場合、引数は Chromosome ではなく Object にする必要があります。

于 2013-05-29T09:00:23.443 に答える
1

RotN卿の答えを少し詳しく説明するには:

このcompareToメソッドは、次の 2 つのプロパティに準拠する必要があります。

  • 比較は対称的です。つまり、if A=BthenB=Aと if A<BthenB>A
  • 比較は推移的です。つまり、 ifA<BB<Cthen A<C、 ifA=BB=Cthenです。A=C

最初のプロパティは比較のために満たされていますが、2 番目のプロパティは満たされていません。投票理論から次の例を考えてみましょう: 3 人の選択肢に投票する 3 人がいます。最高ランクの代替が勝ちます。これにより、どの選択肢も勝てないというあいまいな状況が発生する可能性があることが知られています。


あなたの場合、スコアは人々であり、染色体は選択肢です。問題を示すのに十分なので、5 つのスコアの代わりに 3 だけを使用します。AB、およびの3 つの染色体がありC、スコアは次のとおりです。

A: 1, 2, 3
B: 2, 3, 1
C: 3, 1, 2

A<BB<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;
}
于 2013-05-29T09:57:36.540 に答える
0

あなたが実装しようとしているのは、他のそれぞれよりも大きいスコアが多い場合、ある染色体が別の染色体よりも大きいようです。残念ながら、これは明確な優先順位を提供しません。つまり、それぞれの o1 = o2 と o2 = o3 o1 = o3 が真であることを保証することはできません。これは、順序付けで無限ループにつながるか、より高度なアルゴリズムを使用すると、直面している例外につながる可能性があります。したがって、安定したソートを提供する別のアルゴリズムを見つける必要があります。

アプローチは次のとおりです。

  1. スコアの合計を比較する
  2. スコアの優先順位を定義します (スコア 2 は、スコア 1 が等しい場合にのみ比較されます)。
于 2013-05-29T09:26:00.377 に答える