ここでは、遺伝的アルゴリズムの詳細な原則と具体的な定義は紹介しません。知りたい場合は、Baiduを使用して学習できます。ここでは、遺伝的アルゴリズムの理解を簡単に紹介します。この記事では、遺伝子エンコーディングのバイナリルールを使用しています。
アルゴリズムのアイデア:
遺伝的アルゴリズムは、ダーウィンの進化の理論を指し、種が正の方向(適者の生存)で発達していると考えているため、十分な代数の後、得られた最大値は実際の最大値に非常に近いと考えることができます。
アルゴリズムのステップ:
アルゴリズムの実装-遺伝子部品
1.個人集団(ここでは染色体と見なされる)、個人では、この個人に2つの属性、個人の遺伝子と遺伝子に対応するフィットネス(関数値)を追加します。
パブリッククラス染色体{private boolean [] gene; // gene sequence private double score; //対応する関数スコア} 2。遺伝子配列をランダムに生成します。遺伝子の各位置が0または1であるかどうかにかかわらず、これはそれを達成するための完全にランダムな方法です。
Public Chromosome(int size){if(size <= 0){return; } initgenesize(size); for(int i = 0; i <size; i ++){gene [i] = math.random()> = 0.5; }} private void initgenesize(int size){if(size <= 0){return; } gene = new Boolean [size]; } 3。たとえば、101に対応する数値は5であり、ビット操作が実装するためにビット操作を使用して、対応する値に変換します。
public int getnum(){if(gene == null){return 0; } int num = 0; for(boolean bool:gene){num << = 1; if(bool){num += 1; }} numを返します。 } 4.遺伝子変異が発生した場合、突然変異の位置はランダムな方法で完全に実装されます。突然変異の原理は、1から0、0から1に変更することです。
public void mutation(int num){//変異int size = gene.lengthを許可します。 for(int i = 0; i <num; i ++){//突然変異位置を探します//変異後の値boolean bool =!gene [at];遺伝子[at] = bool; }} 5.クローニング遺伝子は、次世代を生成するために使用されます。このステップは、既存の遺伝子をコピーすることです。
public静的染色体クローン(最終染色体C){if(c == null || c.gene == null){return null; }染色体copy = new Chromosome(); copy.initgenesize(c.gene.length); for(int i = 0; i <c.gene.length; i ++){copy.gene [i] = c.gene [i]; }コピーを返します。 } 6.両方の親が次世代を生み出し、ここで2人の個人が2人の個別の子孫を生産します。どの特定の遺伝子が学生とは異なり、完全にランダムです。
public static list <Chromosome>遺伝子(染色体P1、染色体P2){if(p1 == null || p2 == null){//空で、次世代のリターンnullを生成しない染色体の1つがあります。 } if(p1.gene == null || p2.gene == null){//遺伝子配列がなく、次世代のリターンnullを生成しない染色体の1つがあります。 } if(p1.gene.length!= p2.gene.length){//染色体遺伝子配列の長さは、次世代のリターンnullを生成しません。 }染色体C1 =クローン(P1);染色体C2 =クローン(P2); //クロススワップ位置をランダムに作成しますint size = c1.gene.length; int a =((int)(math.random() * size))%size; int b =((int)(math.random() * size))%size; int min = a> b? B:A; int max = a> b? A:B; //(int i = min; i <= max; i ++){boolean t = c1.gene [i]; c1.gene [i] = c2.gene [i]; c2.gene [i] = t; } list <Chromosome> list = new ArrayList <Chromosome>(); list.add(c1); list.add(c2);返品リスト。 }アルゴリズム実装ジェネティックアルゴリズム
1.遺伝的アルゴリズムについては、対応する集団と設定する必要がある定数が必要です。集団数、遺伝子長、遺伝子変異数、遺伝子変異率など。詳細については、次のコードを参照してください。
パブリックアブストラクトクラスGeneticalGorithm {private list <Chromosome>集団= new ArrayList <Chromosome>(); // Paugutes Private Int Popsize = 100; // Private int genesize; // Private intmiTernum = 500; //最大繰り返しプライベート繰り返し= 0.01;非同期の長さプライベートイントジェネレーション= 1; //現在、いくつの世代が継承されていますか? BestScore; //ベストスコアプライベートダブルワーストスコア; //最悪のスコアプライベートダブルトーカルスコア; //歴史的人口に最適なX値をプライベートダブルyを記録します。 //歴史的人口に最適なy値を記録するprivate int genei; // xyが配置されている場所}} 2。母集団を初期化します。遺伝的アルゴリズムの最初に、元の第一世代である元の集団を初期化する必要があります。
private void init(){for(int i = 0; i <popsize; i ++){eveloges = new arrayList <ChromoSome>();染色体chro =新しい染色体(genesize);人口(chro); } cacultescore(); } 3。最初の母集団が存在した後、人口のフィットネス、および最高のフィットネス、最悪のフィットネス、平均的なフィットネスなどを計算する必要があります。
private void cacultescore(){setchromosomescore(involtion.get(0)); bestscore = involuse.get(0).getScore(); wortscore = eveloge.get(0).getscore(); totalScore = 0; for(染色体chro:集団){setchromosomescore(chro); if(chro.getscore()> bestscore){//最高の遺伝子値bestscore = chro.getscore(); if(y <bestscore){x = changex(chro); y = bestscore; genei = generation; }} if(chro.getScore()<quartScore){//最悪の遺伝子値を設定してください} totalScore += chro.getScore(); } veragesCore = totalScore / popsize; //精度の問題によって引き起こされる平均値は最高の値よりも大きく、平均値を最高の値に設定しますaveragescore = veragescore> bestscore? BestScore:AveragesCore; } 4.個々のフィットネスを計算する場合、遺伝子に基づいて対応するY値を計算する必要があります。ここでは、クラスの実装により特定の実装を実装する2つの抽象的なメソッドを設定します。
private void setchromosomescore(染色体chro){if(chro == null){return; } double x = changex(chro); double y = cacculatey(x); chro.setscore(y); } / ** * @param chro * @return * @description:バイナリを対応するx * / public abstract double changex(chromosome chro)に変換します。 / ** * @param x * @return * @description:x y = f(x) *に基づいてy値を計算します。 5。人口の適合性を計算した後、ターンテーブルギャンブル法を使用して、次世代を生成できる個人を選択する必要があります。ここには、個人のフィットネスが平均的なフィットネス以上の場合にのみ、次世代が生まれるという条件があります(最新のものが生き残る)。
プライベート染色体GetParentChromosome(){double slice = math.random() * totalscore;二重和= 0; for(染色体chro:集団){sum += chro.getscore(); //対応する位置に移動すると、フィットネスは平均的なフィットネス以上です。 }} nullを返します。 } 6.次世代を生み出すことができる個人を選択した後、次世代を生み出すために交配する必要があります。
private void evolve(){list <Chromosome> ChildPopulation = new ArrayList <Chromosome>(); //次世代の母集団を生成します(childpopulation.size()<popsize){chromosome p1 = getParentchromosome();染色体P2 = GetParentChromosome();リスト<染色体>子供= Chromosome.genetic(P1、P2); if(children!= null){for(chromosome chro:children){childpopulation.add(chro); }}} //古い母集団を新しい人口リストに置き換えます<Chromosome> t =集団;人口=子どもの人。 T.Clear(); t = null; //遺伝子変異変異(); //新しい人口のフィットネスを計算しますcacultescore(); } 7.遺伝的変異は、次世代を生成する過程で発生する可能性があります。
private void mutation(){for(chromosome chro:集団){if(math.random()<mutationrate){//遺伝子変異はint mutationnum =(int)(math.random() * maxmutationnum); chro.mutation(mutationnum); }}} 8.上記の手順を1つずつ繰り返します。
public void caculte(){//人口生成を初期化= 1; init(); while(generation <maxiternum){//一般的な遺伝的進化(); print(); Generation ++; }}実装クラスを作成します
上記の遺伝的アルゴリズムのクラスは抽象クラスであるため、[6,106]でy = 100-log(x)の最大値を計算すると仮定して、特定のケースの実装クラスを作成する必要があります。
1.遺伝子の長さは24であると仮定します(遺伝子の長さは必要な結果の有効長によって決定されます)ので、対応するバイナリの最大値は1 << 24です。次の設定を作成します。
public class geneticalGorithmtestは、eneticalGorithm {public static final int num = 1 << 24; public geneticalGorithmtest(){super(24); }} 2。x値の抽象的なメソッドを実装します
@Override public double changex(chromosome chro){// todo auto-eneratedメソッドスタブリターン((1.0 * chro.getnum() / num) * 100) + 6; } 3。yの抽象的な方法を実装します
@Override public double caculatey(double x){// todo auto -enerated method stub Return 100 -math.log(x); }実行結果
遺伝的アルゴリズムについて考えています
私は遺伝的アルゴリズムの多くの紹介を読みました。上記の最適なソリューションは、最後の世代の最も価値があります。質問があります。上記のすべてのバンドの中で最も多くの値、つまりプログラムのXY値、XY値を遺伝的アルゴリズムの最終結果値として使用できないのはなぜですか?
完全なコード
1。染色体クラス
/ ***@説明:遺伝的染色体*/パッケージcom.lulei.genetic.algorithm; java.util.arraylistをインポートします。 java.util.listをインポートします。パブリッククラス染色体{private boolean [] gene; // gene sequence private double score; //対応する関数スコアpublic double getScore(){return score; } public void setScore(double score){this.score = score; } / *** @param size*ランダムに生成された遺伝子配列* / public染色体(intサイズ){if(size <= 0){return; } initgenesize(size); for(int i = 0; i <size; i ++){gene [i] = math.random()> = 0.5; }} / ***新しい遺伝子を生成* / public Chromosome(){} / *** @param c* @return* @description:cloning gene* / public static chromosome clone(最終染色体C){if(c == null || c.gene == null){return null; }染色体copy = new Chromosome(); copy.initgenesize(c.gene.length); for(int i = 0; i <c.gene.length; i ++){copy.gene [i] = c.gene [i]; }コピーを返します。 } / *** @param size* @description:Gene Lengthを初期化* / private void initgenesize(int size){if(size <= 0){return; } gene = new Boolean [size]; } /** * @Param C1 * @Param C2 * @description:次世代を作成する遺伝的生成} if(p1.gene == null || p2.gene == null){//遺伝子配列を持たず、次世代のリターンnullを生成しない染色体の1つがあります。 } if(p1.gene.length!= p2.gene.length){//染色体遺伝子配列の長さは、次世代のリターンnullを生成しません。 }染色体C1 =クローン(P1);染色体C2 =クローン(P2); //クロススワップ位置をランダムに作成しますint size = c1.gene.length; int a =((int)(math.random() * size))%size; int b =((int)(math.random() * size))%size; int min = a> b? B:A; int max = a> b? A:B; //(int i = min; i <= max; i ++){boolean t = c1.gene [i]; c1.gene [i] = c2.gene [i]; c2.gene [i] = t; } list <Chromosome> list = new ArrayList <Chromosome>(); list.add(c1); list.add(c2);返品リスト。 } /*** @param num* @description:Variationは遺伝子num* /public void mutation(int num)のnum位置で発生します(int num){// for(int i = 0; i <num; i ++){//変異位置を検索int =((int)(math.random() * size))%size; //変異後の値boolean bool =!gene [at];遺伝子[at] = bool; }} / *** @return* @description:遺伝子を対応する数字に変換* / public int getNum(){if(gene == null){return 0; } int num = 0; for(boolean bool:gene){num << = 1; if(bool){num += 1; }} numを返します。 }} 2。遺伝子gorithmクラス
/ ** *@説明: */パッケージcom.lulei.genetic.algorithm; java.util.arraylistをインポートします。 java.util.listをインポートします。パブリックアブストラクトクラスGeneticalGorithm {private list <Chromosome>集団= new ArrayList <Chromosome>(); Private int popsize = 100; //人気数字private int genesize; //最大遺伝子長private int maxiternum = 500; //プライベート二重変異体= 0.01; //遺伝子突然変異の確率private int maxmutationnum = 3;プライベートダブルベストスコア。 //歴史的人口に最適なX値をプライベートダブルyを記録します。 //歴史的人口に最適なy値を記録するprivate private int genei; } public void caculte(){//人口生成= 1を初期化します。 init(); while(generation <maxiternum){//一般的な遺伝的進化(); print(); Generation ++; }} / *** @description:出力結果* / private void print(){ System.out.println("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- system.out.println(最悪のスコア); @Description:Private void init(){int i = 0; i <poptsize = new arraylist <chromosome> Private void evolve(){chromosome> new arraylist <chromosome>(); p2) @return *ルーレットメソッドは、次世代を継承できる染色体を選択します。 Chroを返す} @description:Private void cacultescore(人口(0)) setchromosomescore(chro.getscore){// bestscore(y <bestscore){x = chra Chro.getScore += chro.getScore(); (染色体chro:集団){math.random()<mutationrate){//遺伝子変異は、math.random() * maxmutationnum)を発生します。 setchromosomescore(chro == null){chro){chro); @Param X * @Description:x y = f(x) */ public double cacculatey(double x)に基づいています。 this.genesize} setmaxiternum(int maxiternum){maxiternum} Public getBestScore(){return wautscore()} 3。GeneticalGorithMTestクラス
/ ** *@説明: */パッケージcom.lulei.genetic.algorithm; public class geneticalGorithmtestは、eneticalGorithm {public static final int num = 1 << 24; public geneticalGorithmtest(){super(24); } @Override public double changex(chromosome chro){// todo auto-fenated method stub Returt((1.0 * chro.getnum() / num) * 100) + 6; } @Override public double cacculatey(double x){// todo auto -enerated method stub Return 100 -math.log(x); } public static void main(string [] args){geneticalGorithmtest test = new geneticalGorithmtest(); test.caculte(); }}上記は、Java遺伝的アルゴリズムの詳細な紹介です。 Java Genetic Algorithmを学ぶことは誰にとっても役立つことを願っています。