2017-11-01 27 views
4

私が進めている遺伝的アルゴリズムのための異なる選択方法を作成しようとしていますが、すべての選択方法で満たしている問題の1つは、私のフィットネス電卓は非常に基本的であり、すべての私の別の選択方法のいくつかの同一のフィットネスのルーレットホイール選択を使用した遺伝的アルゴリズム

public static Map<String, Double> calculateRouletteSelection(Map<String, Double> population) { 
     String[] keys = new String[population.size()]; 
     Double[] values = new Double[population.size()]; 
     Double[] unsortedValues = new Double[population.size()]; 
     int index = 0; 
     for(Map.Entry<String, Double> mapEntry : population.entrySet()) { 
      keys[index] = mapEntry.getKey(); 
      values[index] = mapEntry.getValue(); 
      unsortedValues[index] = mapEntry.getValue(); 
      index++; 
     } 
     Arrays.sort(values); 
     ArrayList<Integer> numbers = new ArrayList<>(); 
     while(numbers.size() < values.length/2) { 
      int random = rnd.nextInt(values.length); 
      if (!numbers.contains(random)) { 
       numbers.add(random); 
      } 
     } 

     HashMap<String, Double> finalHashMap = new HashMap<>(); 
     for(int i = 0; i<numbers.size(); i++) { 
      for(int j = 0; j<values.length; j++) { 
       if(values[numbers.get(i)] == unsortedValues[j]) { 
        finalHashMap.put(keys[j], unsortedValues[j]); 
       } 
      } 
     } 

     return finalHashMap; 

    } 

90%が同じであるので、私は、私は1のためにそれを解決することができれば、私は確信して得られますので、これは私にとって問題ですすべてを解決することができます。 私が間違っていただければ幸いです

EDITをやって上の任意のヘルプ:私は私は基本的に方法はHashMapの<>にとり何が起こっているかの一般的な動作を掲示することを意図していましたが、に基づいて値をソートし、そのハーフソートされた値をランダムに選択し、対応する染色体を持つ新しいHashMap <に追加します。

+1

ランダムに後でランダムに選択したい場合は、最初にソートするのはなぜですか?とにかく最後に生き残るはずの標本はどれくらいですか?私は "最もふさわしい半分のランダムな半分"のようなものを期待していますが、あなたのコードは人口全体の半分をランダムに選択します。 – daniu

+1

これはこの問題の擬似コードです。 https://stackoverflow.com/questions/177271/roulette-selection-in-genetic-algorithms –

+1

@daniuルーレットホイールの選択アルゴリズムを使用すると、アイテムを最初に並べ替えることをお勧めします。それは目的はランダムな選択は、人口の多様性を維持するために良いと悪い解決策の均一な広がりを持つことだと思う –

答えて

1

コレクションクラスを使う方がずっと良いと思います。

List<Map.Entry<String, Double>> sorted = new ArrayList<>(population.entrySet()); 
// sort by fitness 
Collections.sort(sorted, Comparator.comparing(Map.Entry::getValue)); 

Set<Integer> usedIndices = new HashSet<>(); // keep track of used indices 
Map<String, Double> result = new HashMap<>(); 
while (result.size() < sorted.size()/2) { 
    int index = rnd.nextInt(sorted.size()); 
    if (!usedIndices.add(index)) { 
     continue; // was already used 
    } 
    Map.Entry<String,Double> survivor = sorted.get(index); 
    result.put(survivor.getKey(), survivor.getValue()); 
} 
return result; 

しかし、Sergeyが述べたように、私はこれがあなたのアルゴリズムに必要なものだとは思わない。あなたはより高い適応度を持つ個人に有利に働く必要があります。

0

コメントに記載されているように、ルーレットホイールの選択順序は重要ではなく、重みだけです。ルーレット・ホイールは、ディスクのさまざまな部分を占める異なるセクションを持つ円グラフのようですが、最終的にはすべて単位面積(ディスクの面積)になります。

Javaには同等のものがあるかどうかわかりませんが、C++にはstd::discrete_distributionがあります。これらの整数のそれぞれが選択される確率を表す重みで初期化するディストリビューション[0,n)を生成します。だから、私が普通にやっていることは、配列のエージェントのIDと別の配列の対応する適合値を持つことです。インデックスが一致する限り、順序は重要ではありません。私は適応度の値の配列を離散分布に渡します。これは配列のインデックスとして解釈可能な整数を返します。私はその整数を使って、他の配列からその個体を選択します。

関連する問題