2

私は現在、ナップザックの問題に似ていると考えられる問題を解決するために遺伝的アルゴリズムをコーディングしていますが、差別化要因は、アイテムを複数の「トラック」に保管していることであり、それらの値/重要性は 1 = 最も重要、 3 = 最も重要でない。

これを行う方法は、バイナリ整数の配列を使用することです。0 = トラックに搭載されていない、1 = トラックに搭載されています。

ほとんどの場合、プログラムは必要なことを実行しているように見えます。染色体を比較して、世代ごとに最適な 3 つの個別の染色体を見つける場合を除きます。個々の染色体には同じアイテムを含めることはできません。アイテムは一度に 1 台のトラックにしか搭載できないためです。

これは、染色体を比較するために使用している関数です。

    private int[] getBestSolution(int count)
    {
        int[] Genes = new int[3];
        int min1 = Global.p.population[0].fitness;
        int min2 = Global.p.population[0].fitness;
        int min3 = Global.p.population[0].fitness;
        int ref1 = 0;
        int ref2 = 0;
        int ref3 = 0;
        bool areSame = true;

        //searches for the first "Fittest" chromosome and stores to ref1
        for (int i = 0; i < Global.population; i++)
        {
                if (min1 > Global.p.population[i].fitness)
                {
                    min1 = Global.p.population[i].fitness;
                    ref1 = i;
                }
        }

        //searches for 2nd fittest, while also checking they are different
        for (int i = 0; i < Global.population; i++)
        {
            areSame = arrayCompare(Global.p.population[ref1].chromosome, Global.p.population[i].chromosome);
            if(areSame == true)
            {
                continue;
            }
            if (min2 > Global.p.population[i].fitness)
            {
                min2 = Global.p.population[i].fitness;
                ref2 = i;
            }
        }

        //Searches for 3rd fittest while checking that it is different from the first two
        for (int i = 0; i < Global.population; i++)
        {
            areSame = arrayCompare(Global.p.population[ref1].chromosome, Global.p.population[i].chromosome);
            if (areSame == true)
            {
                continue;
            }
            areSame = arrayCompare(Global.p.population[ref2].chromosome, Global.p.population[i].chromosome);
            if(areSame == true)
            {
                continue;
            }
            if (min3 > Global.p.population[i].fitness)
            {
                min3 = Global.p.population[i].fitness;
                ref3 = i;
            }
        }
        //stores the reference of each chromosome and return
        Genes[0] = ref1;
        Genes[1] = ref2;
        Genes[2] = ref3;
        return Genes;
    }

これは、染色体を以前に選択した染色体と比較して、同じ値が含まれていないことを確認するために使用している関数です。

    public bool arrayCompare(int[] a, int[] b)
    {
        for (int i = 0; i < a.Length; i++)
        {
            if ((a[i] == 1) && b[i] == 1)
            {
                return true;
            }
        }
        return false;
    }

コードのさまざまなポイントでブレークポイントを使用し、値と予想される値をチェックすることで、問題を引き起こしているこれら 2 つの関数に絞り込みました。

最後に、問題自体に。getBestSolution() は、最初の「最適な」値を完全に生成します。2 番目と 3 番目の値は、「population[0].fitness」として初期化された値のままで、表示されます。

値の違う染色体がなければ初期化されたままになると思っていたので、育種の選択基準である育種構造を変えてみました。これと同じ理由で、より大きな集団を使用してテストしたこともあるため、それらは私のコードに問題があるに違いないと考えています。

どんな助けでも大歓迎です。

4

1 に答える 1

0

1. コードに関するメモ。

min1min2、および をmin3、適合度の最大値よりも高い値に初期化する必要がありますGlobal.p.population[0].fitness。この場合、 が集団内で最高の適合度である場合、2 番目と 3 番目の適合度は決して見つからないためです。よりも低いフィットネスGlobal.p.population[0].fitness

2. 使用している遺伝子の確率。

私は間違っているかもしれませんが、あなたが説明した問題に関する私の理論は次のとおりです。

ランダム分布では、1 つの遺伝子に対して、2 人の個人の遺伝子の値の合計 4 つの可能な組み合わせがあります。これらの 4 つの組み合わせでは、2 人の個人が共通してこの遺伝子を に設定していないものが 3 つあります1

               Individual 1    Individual 2   Match criterion    Probability
Combination 1:      0               0               Yes            25% | 
Combination 2:      0               1               Yes            25% | 75%
Combination 3:      1               0               Yes            25% |
Combination 4:      1               1               No             25%

これは、遺伝子が 1 つしかない個体の場合、75% の確率で基準に一致する 2 つの個体を見つけることができることを意味します。つまり、100 個体の遺伝子を比較すると、平均で 75 対の個体が条件に一致することがわかります。しかし、あなたがそれらを見つけることができないいくつかの集団と、あなたがそれらを見つける集団のほとんどがあります.

遺伝子の数が増えるにつれて、パーセンテージは減少します。染色体に 1 つの遺伝子を追加するたびに、基準に一致する個人のパーセンテージに 75/100 を掛ける必要があります。2 つの遺伝子を追加するたびに、パーセンテージに 56.25/100 を掛ける必要があります。

Number of genes         percentage of individuals matching the criterion
      1                                75,00%
      2                                56,25% = 75,00 * 75,00 / 100

      4                                31,64% = 56,25 * 56,25 / 100

      6                                17,79% = 31,64 * 56,25 / 100

      8                                10,01% = 17,79 * 56,25 / 100

    [...]

     16                                 1%

これは、16 個の遺伝子の染色体と 100 個の集団の場合、基準に一致する個人のペアが平均で 1 組見つかることを意味します。基準に一致する 3 人の個人が必要な場合、パーセンテージはさらに小さくなります。6 つの遺伝子の場合、これら 3 つの個体が見つかる確率は約 1.5% です。

問題は、母集団の中に、基準に一致する個体のペアが十分にないことです。

3. アルゴリズムを設計する別の方法。

あなたのアルゴリズムでは、個人をトラックと見なしているようです。別の方法でアルゴリズムを設計します。

遺伝子をアイテムのトラック番号と見なし、必要に応じ0て、アイテムにトラックが割り当てられていないことを示します。

gene[0] = 1 (item 0 is in truck 1)
gene[1] = 0 (item 1 is not in any truck) 
gene[2] = 3 (item 2 is in truck 3)
gene[3] = 2 (item 3 is in truck 2)
gene[4] = 1 (item 4 is in truck 1)

この情報のコード化により、2 番目と 3 番目に優れた個人は、最も優れた個人よりも同じトラックに 1 つのアイテムを持つことができます。例えば:

first best individual:
----------------------
truck1: item1 item2
truck2: item3 item4
truck3: item5 item6 item7
not in any truck: item0

second best individual:
-----------------------
truck1: item1 item3
truck2: item2 item5
truck3: item4 item6
not in any truck: item0 item7

この例では、アイテム 1 は常にトラック 1 にあり、アイテム 6 は常にトラック 3 にあります。

そのため、遺伝子を比較せずに適合度のみをチェックして、2 番目と 3 番目に優れた個体を選択することができます。

于 2016-11-05T07:19:25.593 に答える