2017-05-11 19 views
0

私は現在、遺伝的アルゴリズムを与えられた単語に向かって「生成する」または「進化させる」ようにしています。問題は、たとえそれが突然変異し続けるべきであっても、それが完全にこの言葉に到達することはなく、高すぎるフィットネススコアで停止することである。遺伝的アルゴリズムが突然変異を停止する

相続人例:

ユーザ入力= "HelloWorldの" 500世代= "XelgoWorfd"


そして、私はそれが変異続けない理由見当もつかない。通常、文字列内のいくつかの文字をランダムに変更するだけで再開します。

私は非常にいくつかの助けを喜んでいるでしょう。

ここでステップの説明による基本的なステップがあります:

  1. がゴール単語に比べてスコア完全にランダム化された文字列
  2. フィットネスを計算して20本の染色体を作成します。 (Asciiの数の差を計算する)
  3. 最高のスコアで2つの染色体を仲立ちします。
  4. 一部の染色体をランダムに変異させる(ランダムな文字列を変更する)
  5. 弱い集団の90%を殺し、それをエリート染色体(現時点で最良の適合度を持つ染色体)で置き換える。
  6. すべてを繰り返します。

だからここに私のアルゴリズムの中で最も重要な方法:

public Chromoson[] mate(string gene) { 
    Console.WriteLine("[MATING] In Progress : "+gens+" "+gene); 

    int pivot = (int)Math.Round((double)gens.Length/2) - 1; 

    string child1 = this.gens.Substring(0, pivot) + gene.Substring(pivot); 
    string child2 = gene.Substring(0, pivot) + this.gens.Substring(pivot); 

    Chromoson[] list = new Chromoson[2]; 

    list[0] = new Chromoson(child1); 
    list[1] = new Chromoson(child2); 

    Console.WriteLine("[MATING] Pivot : "+pivot); 
    Console.WriteLine("[MATING] Children : "+child1+" "+child2); 

    return list; 
} 

public void mutate(float chance, int possiblyChanges) { 
    if (random.Next(0,101) <= chance) return; 

    int changes = random.Next(0, possiblyChanges + 1); 
    //int index = (int) Math.Floor((double)random.Next() * this.gens.Length); 

    for (int i = 0; i < changes; i++) { 
     int index = random.Next(0, 13); 
     StringBuilder builder = new StringBuilder(gens); 
     int upOrDown = random.Next(0, 101); 

     if (upOrDown <= 50 && (int)builder[index] > 0 && chars.Contains(Convert.ToChar(builder[index] - 1))) 
      builder[index] = Convert.ToChar(builder[index] - 1); 
     else if (upOrDown >= 50 && (int)builder[index] < 127 && chars.Contains(Convert.ToChar(builder[index] + 1))) 
      builder[index] = Convert.ToChar(builder[index] + 1); 
     else 
      mutate(chance, possiblyChanges); 

     gens = builder.ToString(); 
    } 
    Console.WriteLine("[MUTATING] In Progress"); 
} 

public void calculateCost(string otherGens) 
{ 
    int total = 0; 
    for (int i = 0; i < gens.Length; i++) 
    { 
     total += (((int)gens[i] - (int)otherGens[i]) * ((int)gens[i] - (int)otherGens[i])) * (i*i); 
    } 
    Console.WriteLine("[CALCULATING] Costs : " + total); 
    this.cost = total; 
} 
+0

迷惑メールにタグを付けないでください。 – shmosel

+0

ランダムである可能性がありますか? if(random.Next(0,101)<= chance)return; –

+1

これは完全なコードではありません。 [最小、完全、検証可能な例](http://stackoverflow.com/help/mcve)を投稿してください。 – bc004346

答えて

1

何かがあなたのタイムステップで完全にオフになっている:

  1. 完全にランダム化文字列で20本の染色体を作成します。 と思われます。
  2. 目標単語と比較したフィットネススコアを計算します。 (アスキーの数の差を数える)。 と思われます。
  3. 最高のスコアで2つの染色体を交配する。 何ですか?新しい人口を作るために2つの最もふさわしい染色体を繁殖させるだけですか?つまり、ほぼ完全に類似した人口を持つことになります。比例Breedfitnessので、すべてのゲノムを子孫
  4. はキルに
  5. (ランダムな文字列の文字を変更)ランダムに弱い人口の90%に染色体の一部を変異させるとエリート染色体(染色体に置き換える持ってチャンスを持っています現在最高のフィットネススコアで)。 あなたは90%を殺しますか?だから、基本的には、反復ごとに2つのベストゲノムを維持しておき、他の18個をステップ1に置き換えていますか?あなたが望むのは、ステップ3で2つの適性を保ち、繁殖によって他の18人を作り出すことです。
  6. すべてを繰り返します。

    INIT:

だからあなたに手順を変更します。人口を初期化し、20本のランダムな染色体

  1. にそれぞれの計算スコアを作成します(エリート主義別名)次の集団に
  2. 保存2本の適者生存の染色体をchromsome、
  3. 比例フィットネスを繁殖することにより、他の18人のに必要な個人をgetthe chromsomesを変異させます特定のチャンスで

  • を繰り返し、ランダムな個人ごとのラウンドを作成しないでください。これにより、あなたのアルゴリズムはランダムな検索に変わります。

  • +0

    ありがとう:D助けて! – genaray

    1

    あなた変異しcalculateCost機能は奇妙です。特に、mutate()はローカルミニマにトラップされるように設計されています。どのような突然変異もエリートよりも悪くなります(これはおそらく同一であるため、クロスオーバは何も変わりません)。別の突然変異を使用する:ランダムなインデックスを選んで完全に変更します。また、cost()からi * iを削除します。

    関連する問題