遺傳算法探索

遺傳算法

適者生存。”適“的是什麼?是我們身邊的環境還是上帝的指引?
自然界的生物不管情願與否都被刻畫着。有一條無形的手指引着人類前進的方向。
遺傳算法,一個程序員自己刻畫世界的方式。遺傳算法通過模擬自然界的交叉變異,保證了問題的搜索空間。通過適應度函數刻畫程序員自己的世界。


遺傳算法本身是神經網絡的前身。遺傳算法的適應度函數和神經網絡的損失函數本質一樣。都是描述正解和現在得到解的差別。前期的神經網絡就是通過遺傳算法當作損失函數的。

關於遺傳算法的實現細節


一般的遺傳算法都有一個交配概率(又稱爲交叉概率),範圍一般是0.6~1,這個交配概率反映兩個被選中的個體進行交配的概率。例如,交配概率爲0.8,則80%的“夫妻”會生育後代。每兩個個體通過交配產生兩個新個體,代替原來的“老”個體,而不交配的個體則保持不變。–維基百科

c語言代碼

#include <stdio.h>
#include <stdlib.h>

struct Population{
    int gene[11];//基因爲0,1組成
    double x;//基因型轉化爲表現型
    double y;
};
/*
求y=x*x的最小值,x取值範圍爲【-1,1】精度爲0.001,所以基因位爲11

*/
//初始種羣
void initPopulation(struct Population *population,int populationNum){
    srand((unsigned)time(NULL));
    for(int i=0;i<populationNum;i++){
      population[i].x=-1;
      for(int j=0;j<11;j++){
        population[i].gene[j]=rand()%2;//隨機數
      }
      printf("init gene[%d]=",i);
      for(int j=0;j<11;j++){
        printf("%d",population[i].gene[j]);
      }
      printf("\n");
    }
}

//基因型轉化爲表現型
void bitToNum(struct Population *population,int populationNum){
    for(int i=0;i<populationNum;i++){
            population[i].x=-1;
            int count=1;//進位符
        for(int j=10;j>=0;j--){
            population[i].x+=population[i].gene[j]*count*0.001;
            count*=2;
        }
        //printf("x=:%lf\n",population[i].x);
    }
    printf("\n");
}

//計算適應度函數
void fitness(struct Population *population,int populationNum){
    for(int i=0;i<populationNum;i++){
        population[i].y=population[i].x*population[i].x;//y=x*x
        printf("y=:%lf\n",population[i].y);
    }
}

//選擇
void selection(struct Population *population,struct Population *crossoverPopulation,int populationNum){

/*使用輪盤賭算法進行選擇,因爲該遺傳算法是求最小值,所以不能直接對fitness輪盤賭,通過一頓花裏胡哨的倒數歸一化操作,*/
    double total=0,sum=0;
    for(int i = 0;i<populationNum;i++){
        total+=((double)population[i].y);
    }
    for(int i = 0;i<populationNum;i++){
        sum+=(total/population[i].y);
    }
    double num,temp,rate;
    for(int i=0;i<2*populationNum;i++){
        num = 0;
        temp = (rand()%100000)*0.00001;
        for(int j=0;j<populationNum;j++){
            num+=(total/population[j].y);

            double rate = (double)num/sum;
            if(temp <=rate){
                for(int k=0;k<11;k++){
                    crossoverPopulation[i].gene[k]=population[j].gene[k];
                }
                break;
            }
        }
    }
}
//交叉
void crossover(struct Population *population,struct Population *crossoverPopulation,int populationNum,double pc){
    int probability,pos;
    for(int i = 0;i<populationNum;i++){
        probability = rand()%100;
        if(probability<=pc*100){
            pos == rand()%11;
            for(int k=0;k<11;k++){
                if(k<=pos){
                    population[i].gene[k]=crossoverPopulation[i].gene[k];
                }else{
                    population[i].gene[k]=crossoverPopulation[i+populationNum].gene[k];
                }
            }
        }
    }
}
//變異
void mutation(struct Population *population,int populationNum,double pm){
    int probability,pos;
    for(int i=0;i<populationNum;i++){
        probability = rand()%100;
        if(probability<pm*100){
            pos=rand()%10;
            if(population[i].gene[pos]==1){
                population[i].gene[pos]=0;
            }else{
                population[i].gene[pos]=1;
            }
        }
    }
}

int main()
{
    int populationNum=10;//初始種羣大小
    double pc=0.8;//交叉概率
    double pm=0.03;//變異概率
    int generationNum=1000;//訓練代數
    struct Population population[populationNum];
    struct Population crossoverPopulation[2*populationNum];
    initPopulation(population,populationNum);
    for(int i=0;i<generationNum;i++){
        bitToNum(population,populationNum);
        fitness(population,populationNum);
        selection(population,crossoverPopulation,populationNum);
        crossover(population,crossoverPopulation,populationNum,pc);
        mutation(population,populationNum,pm);
        printf("\n");
    }
    printf("train finishing!!!");
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章