• 遗传算法---编程小试


    利用遗传算法求解min  f(x) = (x-0.5)2+|x-3|   x取值范围是[-1,1]。

    不同的选择下一代的方式,有着不一样的表现,其中最后一种策略效果最好。

    CGA

      1 #include <stdio.h>     //定义输入/输出函数
      2 #include <stdlib.h>    //定义杂项函数及内存分配函数
      3 #include <ctime>
      4 #include <cstdlib>
      5 #include <string>
      6 #include <sstream>
      7 #include <iostream>
      8 #include <fstream>
      9 #include <cmath>
     10 using namespace std;
     11 
     12 //目标函数
     13 double bar_func(double x){
     14     return  pow(x-0.5,2)+abs(x+3);
     15 }
     16 
     17 //得到编码长度
     18 int get_m(int a,int b,int u){
     19     int m = 1;
     20     int temp = (b-a)*pow(10,u);
     21     while(1){
     22         if(temp<=pow(2,m)-1&&temp>pow(2,m-1)-1){
     23             return m;
     24             break;
     25         }
     26         else
     27             m = m+1;
     28     }
     29 }
     30 
     31 //适应度函数
     32 double Fit(double x){
     33     int M = -3;
     34     return 1/(bar_func(x)+M);
     35 }
     36 
     37 //对种群进行初始化
     38 void init(string B[],int N,int m){
     39     srand((unsigned)time(NULL) );
     40     for(int i=0;i<N;i++){
     41         B[i] = "";
     42         for(int j=0;j<m;j++){
     43             if(rand()%2==1) B[i]+="1";
     44             else B[i]+="0";
     45         }
     46     }
     47     return;
     48 }
     49 
     50 //double x = a+ (b-a)*x1/(2^m -1)
     51 double get_x(string B[],int pos,int a,int b,int m){
     52     double res = 0,x1=0;
     53     for(int i=0;i<m;i++){
     54         x1= x1*2 + B[pos][i]-'0';
     55     }
     56     res = a + (b-a)*x1/(pow(2,m)-1);
     57     return res;
     58 }
     59 
     60 int main(){
     61     //0.参数
     62     int a = -1;       //自变量取值区间下界
     63     int b = 1;        //自变量取值区间上界
     64     int u = 5;        //精度要求
     65     int m ;           //编码长度
     66     double pc = 0.2;  //交叉的概率
     67     double pm = 0.001;//变异的概率
     68     int l = 5;        //交叉长度 m-l
     69     int t = 400;      //迭代次数
     70     int N = 40;       //种群规模
     71     string B[N];      //初始种群
     72 
     73     m = get_m(a,b,u); //得到编码长度
     74     init(B,N,m);      //对种群进行初始化
     75     srand((unsigned)time(NULL) );
     76 
     77     //每一代的操作都一样
     78     for(int o=0;o<t;o++){
     79 
     80         //1.选择进化的父母
     81         double sum_Fit =  0;
     82         double pi[N];      //每代被选中的概率
     83         double qi[N] ;     //计算累计概率
     84         string Next_B[N];  //用于进化的父母
     85         for(int i=0;i<N;i++) sum_Fit+= Fit(get_x(B,i,a,b,m) ) ;
     86         for(int i=0;i<N;i++) pi[i] = Fit(get_x(B,i,a,b,m))/sum_Fit;
     87         for(int i=0;i<N;i++){
     88             for(int j=0;j<=i;j++){
     89                 qi[i] +=pi[j] ;
     90             }
     91         }
     92         for(int i=0;i<N;i++){
     93             double rand_temp0 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
     94             if(rand_temp0>=0&&rand_temp0<=qi[0]){
     95                     Next_B[i] = B[0];
     96                     continue;
     97             }
     98             for(int j=1;j<N;j++){
     99                 if(rand_temp0>qi[j-1]&&rand_temp0<=qi[j] ){
    100                     Next_B[i] = B[j];
    101                     continue;
    102                 }
    103             }
    104         }
    105 
    106 
    107         //2.交叉计算
    108         int num1 = 0;        //参与交叉的个体数量
    109         int num2 = 0;        //未参与交叉的个体的数量
    110         string temp1_B[N];   //参与交叉的个体
    111         string temp2_B[N];   //未参与交叉的个体
    112         string recombin_B[N];//交叉过的个体
    113         for(int i=0;i<N;i++){
    114             double rand_temp1 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
    115             if(rand_temp1<=pc ){
    116                 temp1_B[num1++] = Next_B[i];
    117             }
    118             else
    119                 temp2_B[num2++] = Next_B[i];
    120         }
    121         //如果上面选出的参与交叉的个体的数量为奇数,那么就去掉一个
    122         if(num1%2==1) {
    123             num1--;
    124             temp2_B[num2++] = temp1_B[num1];
    125         }
    126         //对于没有参与交叉的点直接看成本身的后代
    127         for(int i=0;i<num2;i++){
    128             recombin_B[i] = temp2_B[i];
    129         }
    130         //进行交叉操作
    131         for(int i=0;i<num1;i=i+2){
    132             string temp = temp1_B[i].substr(l,m-l);          //交叉起始点l在前面已经定义
    133             temp1_B[i] = temp1_B[i].substr(0,l)+temp1_B[i+1].substr(l,m-l);
    134             temp1_B[i+1] = temp1_B[i+1].substr(0,l)+temp;
    135         }
    136         //将交叉后的个体存入recombin_B
    137         for(int i=num2,j=0;i<N;i++,j++){
    138             recombin_B[i] = temp1_B[j];
    139         }
    140 
    141 
    142         //3.变异计算
    143         string varia_B[N];     //变异个体
    144         int varia_temp[N][m] ; //string不好操作,换成数组
    145         for(int i=0;i<N;i++){
    146             for(int j=0;j<m;j++){
    147                  varia_temp[i][j] = 0;
    148             }
    149         }
    150         for(int i=0;i<N;i++){
    151             for(int j=0;j<m;j++){
    152                  double rand_temp2 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
    153                  if(rand_temp2<=pm){
    154                     if((recombin_B[i][j]-'0')==1) varia_temp[i][j]==0;
    155                     else varia_temp[i][j]==1;
    156                  }
    157                  else varia_temp[i][j] =recombin_B[i][j]-'0';
    158             }
    159         }
    160         for(int i=0;i<N;i++){
    161             varia_B[i] = "";
    162             for(int j=0;j<m;j++){
    163                 if(varia_temp[i][j]==1) varia_B[i]+="1";
    164                 else varia_B[i]+="0";
    165             }
    166         }
    167 
    168         //4.选择下一代
    169         double sum_Fit_next =  0;
    170         double pi_next[N];      //每代被选中的概率
    171         double qi_next[N] ;     //计算累计概率
    172         for(int i=0;i<N;i++) sum_Fit_next+= Fit(get_x(varia_B,i,a,b,m) ) ;
    173         for(int i=0;i<N;i++) pi_next[i] = Fit(get_x(varia_B,i,a,b,m))/sum_Fit_next;
    174         for(int i=0;i<N;i++){
    175             for(int j=0;j<=i;j++){
    176                 qi_next[i] +=pi_next[j] ;
    177             }
    178         }
    179         for(int i=0;i<N;i++){
    180             double rand_temp0 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
    181             if(rand_temp0>=0&&rand_temp0<=qi_next[0]){
    182                     B[i] = varia_B[0];
    183                     continue;
    184             }
    185             for(int j=1;j<N;j++){
    186                 if(rand_temp0>qi_next[j-1]&&rand_temp0<=qi_next[j] ){
    187                     B[i] = varia_B[j];
    188                     continue;
    189                 }
    190             }
    191         }
    192 
    193 
    194     }
    195 
    196     //输出结果
    197     double x_res = get_x(B,0,a,b,m);
    198     cout<<x_res<<endl<<bar_func(x_res)<<endl;
    199 
    200     system("pause");
    201     return 0;
    202 }
    CGA

    revise_CGA

      1 #include <stdio.h>     //定义输入/输出函数
      2 #include <stdlib.h>    //定义杂项函数及内存分配函数
      3 #include <ctime>
      4 #include <cstdlib>
      5 #include <string>
      6 #include <sstream>
      7 #include <iostream>
      8 #include <fstream>
      9 #include <cmath>
     10 using namespace std;
     11 
     12 //目标函数
     13 double bar_func(double x){
     14     return  pow(x-0.5,2)+abs(x+3);
     15 }
     16 
     17 //得到编码长度
     18 int get_m(int a,int b,int u){
     19     int m = 1;
     20     int temp = (b-a)*pow(10,u);
     21     while(1){
     22         if(temp<=pow(2,m)-1&&temp>pow(2,m-1)-1){
     23             return m;
     24             break;
     25         }
     26         else
     27             m = m+1;
     28     }
     29 }
     30 
     31 //适应度函数
     32 double Fit(double x){
     33     int M = -3;
     34     return 1/(bar_func(x)+M);
     35 }
     36 
     37 //对种群进行初始化
     38 void init(string B[],int N,int m){
     39     srand((unsigned)time(NULL) );
     40     for(int i=0;i<N;i++){
     41         B[i] = "";
     42         for(int j=0;j<m;j++){
     43             if(rand()%2==1) B[i]+="1";
     44             else B[i]+="0";
     45         }
     46     }
     47     return;
     48 }
     49 
     50 //double x = a+ (b-a)*x1/(2^m -1)
     51 double get_x(string B[],int pos,int a,int b,int m){
     52     double res = 0,x1=0;
     53     for(int i=0;i<m;i++){
     54         x1= x1*2 + B[pos][i]-'0';
     55     }
     56     res = a + (b-a)*x1/(pow(2,m)-1);
     57     return res;
     58 }
     59 
     60 double get_x_best(string bestRes,int a,int b,int m){
     61     double res = 0,x1=0;
     62     for(int i=0;i<m;i++){
     63         x1= x1*2 + bestRes[i]-'0';
     64     }
     65     res = a + (b-a)*x1/(pow(2,m)-1);
     66     return res;
     67 }
     68 
     69 int main(){
     70     //0.参数
     71     int a = -1;       //自变量取值区间下界
     72     int b = 1;        //自变量取值区间上界
     73     int u = 5;        //精度要求
     74     int m ;           //编码长度
     75     double pc = 0.2;  //交叉的概率
     76     double pm = 0.001;//变异的概率
     77     int l = 5;        //交叉长度 m-l
     78     int t = 400;      //迭代次数
     79     int N = 40;       //种群规模
     80     string B[N];      //初始种群
     81     string bestRes;   //超级个体
     82 
     83     m = get_m(a,b,u); //得到编码长度
     84     init(B,N,m);      //对种群进行初始化
     85     bestRes = B[0];   //初始化超级个体
     86     srand((unsigned)time(NULL) );
     87 
     88     //每一代的操作都一样
     89     for(int o=0;o<t;o++){
     90 
     91         //1.选择进化的父母
     92         double sum_Fit =  0;
     93         double pi[N];      //每代被选中的概率
     94         double qi[N];      //计算累计概率
     95         string Next_B[N];  //用于进化的父母
     96         for(int i=0;i<N;i++) sum_Fit+= Fit(get_x(B,i,a,b,m) ) ;
     97         for(int i=0;i<N;i++) pi[i] = Fit(get_x(B,i,a,b,m))/sum_Fit;
     98         for(int i=0;i<N;i++){
     99             for(int j=0;j<=i;j++){
    100                 qi[i] +=pi[j] ;
    101             }
    102         }
    103         for(int i=0;i<N;i++){
    104             double rand_temp0 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
    105             if(rand_temp0>=0&&rand_temp0<=qi[0]){
    106                     Next_B[i] = B[0];
    107                     continue;
    108             }
    109             for(int j=1;j<N;j++){
    110                 if(rand_temp0>qi[j-1]&&rand_temp0<=qi[j] ){
    111                     Next_B[i] = B[j];
    112                     continue;
    113                 }
    114             }
    115         }
    116 
    117 
    118         //2.交叉计算
    119         int num1 = 0;        //参与交叉的个体数量
    120         int num2 = 0;        //未参与交叉的个体的数量
    121         string temp1_B[N];   //参与交叉的个体
    122         string temp2_B[N];   //未参与交叉的个体
    123         string recombin_B[N];//交叉过的个体
    124         for(int i=0;i<N;i++){
    125             double rand_temp1 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
    126             if(rand_temp1<=pc ){
    127                 temp1_B[num1++] = Next_B[i];
    128             }
    129             else
    130                 temp2_B[num2++] = Next_B[i];
    131         }
    132         //如果上面选出的参与交叉的个体的数量为奇数,那么就去掉一个
    133         if(num1%2==1) {
    134             num1--;
    135             temp2_B[num2++] = temp1_B[num1];
    136         }
    137         //对于没有参与交叉的点直接看成本身的后代
    138         for(int i=0;i<num2;i++){
    139             recombin_B[i] = temp2_B[i];
    140         }
    141         //进行交叉操作
    142         for(int i=0;i<num1;i=i+2){
    143             string temp = temp1_B[i].substr(l,m-l);          //交叉起始点l在前面已经定义
    144             temp1_B[i] = temp1_B[i].substr(0,l)+temp1_B[i+1].substr(l,m-l);
    145             temp1_B[i+1] = temp1_B[i+1].substr(0,l)+temp;
    146         }
    147         //将交叉后的个体存入recombin_B
    148         for(int i=num2,j=0;i<N;i++,j++){
    149             recombin_B[i] = temp1_B[j];
    150         }
    151 
    152 
    153         //3.变异计算
    154         string varia_B[N];     //变异个体
    155         int varia_temp[N][m] ; //string不好操作,换成数组
    156         for(int i=0;i<N;i++){
    157             for(int j=0;j<m;j++){
    158                  varia_temp[i][j] = 0;
    159             }
    160         }
    161         for(int i=0;i<N;i++){
    162             for(int j=0;j<m;j++){
    163                  double rand_temp2 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
    164                  if(rand_temp2<=pm){
    165                     if((recombin_B[i][j]-'0')==1) varia_temp[i][j]==0;
    166                     else varia_temp[i][j]==1;
    167                  }
    168                  else varia_temp[i][j] =recombin_B[i][j]-'0';
    169             }
    170         }
    171         for(int i=0;i<N;i++){
    172             varia_B[i] = "";
    173             for(int j=0;j<m;j++){
    174                 if(varia_temp[i][j]==1) varia_B[i]+="1";
    175                 else varia_B[i]+="0";
    176             }
    177         }
    178 
    179 
    180         //4.选择下一代
    181         double sum_Fit_next =  0;
    182         double pi_next[N];      //每代被选中的概率
    183         double qi_next[N] ;     //计算累计概率
    184         for(int i=0;i<N;i++) sum_Fit_next+= Fit(get_x(varia_B,i,a,b,m) ) ;
    185         for(int i=0;i<N;i++) pi_next[i] = Fit(get_x(varia_B,i,a,b,m))/sum_Fit_next;
    186         for(int i=0;i<N;i++){
    187             for(int j=0;j<=i;j++){
    188                 qi_next[i] +=pi_next[j] ;
    189             }
    190         }
    191         for(int i=0;i<N;i++){
    192             double rand_temp0 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
    193             if(rand_temp0>=0&&rand_temp0<=qi_next[0]){
    194                     B[i] = varia_B[0];
    195                     continue;
    196             }
    197             for(int j=1;j<N;j++){
    198                 if(rand_temp0>qi_next[j-1]&&rand_temp0<=qi_next[j] ){
    199                     B[i] = varia_B[j];
    200                     continue;
    201                 }
    202             }
    203         }
    204 
    205         //保留最好的个体作为超级个体
    206         for(int i=0;i<N;i++){
    207             double temp_best = Fit( get_x_best( bestRes,a,b,m));
    208             if(Fit( get_x(B,i,a,b,m) )> temp_best)  {
    209                 bestRes = B[i];
    210                 temp_best = Fit( get_x_best( bestRes,a,b,m));
    211             }
    212         }
    213 
    214 
    215     }
    216 
    217     //输出结果
    218     double x_res = get_x_best( bestRes,a,b,m);
    219     cout<<x_res<<endl<<bar_func(x_res)<<endl;
    220     system("pause");
    221     return 0;
    222 }
    revise_CGA

    直接把变异后的个体当成下一代,进行进化

      1 #include <stdio.h>     //定义输入/输出函数
      2 #include <stdlib.h>    //定义杂项函数及内存分配函数
      3 #include <ctime>
      4 #include <cstdlib>
      5 #include <string>
      6 #include <sstream>
      7 #include <iostream>
      8 #include <fstream>
      9 #include <cmath>
     10 using namespace std;
     11 
     12 //目标函数
     13 double bar_func(double x){
     14     return  pow(x-0.5,2)+abs(x+3);
     15 }
     16 
     17 //得到编码长度
     18 int get_m(int a,int b,int u){
     19     int m = 1;
     20     int temp = (b-a)*pow(10,u);
     21     while(1){
     22         if(temp<=pow(2,m)-1&&temp>pow(2,m-1)-1){
     23             return m;
     24             break;
     25         }
     26         else
     27             m = m+1;
     28     }
     29 }
     30 
     31 //适应度函数
     32 double Fit(double x){
     33     int M = -3;
     34     return 1/(bar_func(x)+M);
     35 }
     36 
     37 //对种群进行初始化
     38 void init(string B[],int N,int m){
     39     srand((unsigned)time(NULL) );
     40     for(int i=0;i<N;i++){
     41         B[i] = "";
     42         for(int j=0;j<m;j++){
     43             if(rand()%2==1) B[i]+="1";
     44             else B[i]+="0";
     45         }
     46     }
     47     return;
     48 }
     49 
     50 //double x = a+ (b-a)*x1/(2^m -1)
     51 double get_x(string B[],int pos,int a,int b,int m){
     52     double res = 0,x1=0;
     53     for(int i=0;i<m;i++){
     54         x1= x1*2 + B[pos][i]-'0';
     55     }
     56     res = a + (b-a)*x1/(pow(2,m)-1);
     57     return res;
     58 }
     59 
     60 int main(){
     61     //0.参数
     62     int a = -1;       //自变量取值区间下界
     63     int b = 1;        //自变量取值区间上界
     64     int u = 5;        //精度要求
     65     int m ;           //编码长度
     66     double pc = 0.2;  //交叉的概率
     67     double pm = 0.001;//变异的概率
     68     int l = 5;        //交叉长度 m-l
     69     int t = 400;      //迭代次数
     70     int N = 40;       //种群规模
     71     string B[N];      //初始种群
     72 
     73     m = get_m(a,b,u); //得到编码长度
     74     init(B,N,m);      //对种群进行初始化
     75     srand((unsigned)time(NULL) );
     76 
     77     //每一代的操作都一样
     78     for(int o=0;o<t;o++){
     79 
     80         //1.选择进化的父母
     81         double sum_Fit =  0;
     82         double pi[N];      //每代被选中的概率
     83         double qi[N] ;     //计算累计概率
     84         string Next_B[N];  //用于进化的父母
     85         for(int i=0;i<N;i++) sum_Fit+= Fit(get_x(B,i,a,b,m) ) ;
     86         for(int i=0;i<N;i++) pi[i] = Fit(get_x(B,i,a,b,m))/sum_Fit;
     87         for(int i=0;i<N;i++){
     88             for(int j=0;j<=i;j++){
     89                 qi[i] +=pi[j] ;
     90             }
     91         }
     92         for(int i=0;i<N;i++){
     93             double rand_temp0 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
     94             if(rand_temp0>=0&&rand_temp0<=qi[0]){
     95                     Next_B[i] = B[0];
     96                     continue;
     97             }
     98             for(int j=1;j<N;j++){
     99                 if(rand_temp0>qi[j-1]&&rand_temp0<=qi[j] ){
    100                     Next_B[i] = B[j];
    101                     continue;
    102                 }
    103             }
    104         }
    105 
    106 
    107         //2.交叉计算
    108         int num1 = 0;        //参与交叉的个体数量
    109         int num2 = 0;        //未参与交叉的个体的数量
    110         string temp1_B[N];   //参与交叉的个体
    111         string temp2_B[N];   //未参与交叉的个体
    112         string recombin_B[N];//交叉过的个体
    113         for(int i=0;i<N;i++){
    114             double rand_temp1 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
    115             if(rand_temp1<=pc ){
    116                 temp1_B[num1++] = Next_B[i];
    117             }
    118             else
    119                 temp2_B[num2++] = Next_B[i];
    120         }
    121         //如果上面选出的参与交叉的个体的数量为奇数,那么就去掉一个
    122         if(num1%2==1) {
    123             num1--;
    124             temp2_B[num2++] = temp1_B[num1];
    125         }
    126         //对于没有参与交叉的点直接看成本身的后代
    127         for(int i=0;i<num2;i++){
    128             recombin_B[i] = temp2_B[i];
    129         }
    130         //进行交叉操作
    131         for(int i=0;i<num1;i=i+2){
    132             string temp = temp1_B[i].substr(l,m-l);          //交叉起始点l在前面已经定义
    133             temp1_B[i] = temp1_B[i].substr(0,l)+temp1_B[i+1].substr(l,m-l);
    134             temp1_B[i+1] = temp1_B[i+1].substr(0,l)+temp;
    135         }
    136         //将交叉后的个体存入recombin_B
    137         for(int i=num2,j=0;i<N;i++,j++){
    138             recombin_B[i] = temp1_B[j];
    139         }
    140 
    141 
    142         //3.变异计算
    143         string varia_B[N];     //变异个体
    144         int varia_temp[N][m] ; //string不好操作,换成数组
    145         for(int i=0;i<N;i++){
    146             for(int j=0;j<m;j++){
    147                  varia_temp[i][j] = 0;
    148             }
    149         }
    150         for(int i=0;i<N;i++){
    151             for(int j=0;j<m;j++){
    152                  double rand_temp2 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
    153                  if(rand_temp2<=pm){
    154                     if((recombin_B[i][j]-'0')==1) varia_temp[i][j]==0;
    155                     else varia_temp[i][j]==1;
    156                  }
    157                  else varia_temp[i][j] =recombin_B[i][j]-'0';
    158             }
    159         }
    160         for(int i=0;i<N;i++){
    161             varia_B[i] = "";
    162             for(int j=0;j<m;j++){
    163                 if(varia_temp[i][j]==1) varia_B[i]+="1";
    164                 else varia_B[i]+="0";
    165             }
    166         }
    167 
    168         //4.选择下一代
    169         for(int i=0;i<N;i++){
    170             B[i] = varia_B[i];
    171         }
    172 
    173 
    174     }
    175 
    176     //输出结果
    177     double x_res = get_x(B,0,a,b,m);
    178     cout<<x_res<<endl<<bar_func(x_res)<<endl;
    179 
    180     system("pause");
    181     return 0;
    182 }
    View Code

    选择最好的N个个体作为下一代,进行进化

    #include <stdlib.h>
    #include <stdio.h>     //定义输入/输出函数
    #include <stdlib.h>    //定义杂项函数及内存分配函数
    #include <ctime>
    #include <cstdlib>
    #include <string>
    #include <sstream>
    #include <iostream>
    #include <fstream>
    #include <cmath>
    using namespace std;
    
    //目标函数
    double bar_func(double x){
        return  pow(x-0.5,2)+abs(x+3);
    }
    
    //得到编码长度
    int get_m(int a,int b,int u){
        int m = 1;
        int temp = (b-a)*pow(10,u);
        while(1){
            if(temp<=pow(2,m)-1&&temp>pow(2,m-1)-1){
                return m;
                break;
            }
            else
                m = m+1;
        }
    }
    
    //适应度函数
    double Fit(double x){
        int M = -3;
        return 1/(bar_func(x)+M);
    }
    
    //对种群进行初始化
    void init(string B[],int N,int m){
        srand((unsigned)time(NULL) );
        for(int i=0;i<N;i++){
        	B[i] = "";
            for(int j=0;j<m;j++){
            	if(rand()%2==1) B[i]+="1";
                else B[i]+="0";
            }
        }
        return;
    }
    
    //double x = a+ (b-a)*x1/(2^m -1)
    double get_x(string B[],int pos,int a,int b,int m){
    	double res = 0,x1=0;
    	for(int i=0;i<18;i++){
    		x1= x1*2 + B[pos][i]-'0';
    	}
    	res = a + (b-a)*x1/(pow(2,m)-1);
    	return res;
    }
    
    int main(){
        //0.参数
        int a = -1;       //自变量取值区间下界
        int b = 1;        //自变量取值区间上界
        int u = 5;        //精度要求
        int m ;           //编码长度
        double pc = 0.2;  //交叉的概率
        double pm = 0.001;//变异的概率
        int l = 5;        //交叉长度 m-l
        int t = 400;      //迭代次数
        int N = 40;       //种群规模
        string B[N];      //初始种群
    
        m = get_m(a,b,u); //得到编码长度
        init(B,N,m);      //对种群进行初始化
    	srand((unsigned)time(NULL) );
    
        //每一代的操作都一样
        for(int o=0;o<t;o++){
    
            //1.选择进化的父母
            double sum_Fit =  0;
            double pi[N];      //每代被选中的概率
            double qi[N] ;     //计算累计概率
            string Next_B[N];  //用于进化的父母
            for(int i=0;i<N;i++) sum_Fit+= Fit(get_x(B,i,a,b,m) ) ;
            for(int i=0;i<N;i++) pi[i] = Fit(get_x(B,i,a,b,m))/sum_Fit;
    		for(int i=0;i<N;i++){
    			for(int j=0;j<=i;j++){
    				qi[i] +=pi[j] ;
    			}
    		}
            for(int i=0;i<N;i++){
            	double rand_temp0 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
            	if(rand_temp0>=0&&rand_temp0<=qi[0]){
            			Next_B[i] = B[0];
            			continue;
                }
            	for(int j=1;j<N;j++){
    				if(rand_temp0>qi[j-1]&&rand_temp0<=qi[j] ){
    					Next_B[i] = B[j];
    					continue;
    				}
    			}
    		}
    
    
            //2.交叉计算
            int num1 = 0;        //参与交叉的个体数量
            int num2 = 0;        //未参与交叉的个体的数量
            string temp1_B[N];   //参与交叉的个体
            string temp2_B[N];   //未参与交叉的个体
            string recombin_B[N];//交叉过的个体
            for(int i=0;i<N;i++){
                double rand_temp1 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
                if(rand_temp1<=pc ){
                    temp1_B[num1++] = Next_B[i];
                }
                else
                    temp2_B[num2++] = Next_B[i];
            }
            //如果上面选出的参与交叉的个体的数量为奇数,那么就去掉一个
            if(num1%2==1) {
                num1--;
                temp2_B[num2++] = temp1_B[num1];
            }
            //对于没有参与交叉的点直接看成本身的后代
            for(int i=0;i<num2;i++){
                recombin_B[i] = temp2_B[i];
            }
            //进行交叉操作
            for(int i=0;i<num1;i=i+2){
                string temp = temp1_B[i].substr(l,m-l);          //交叉起始点l在前面已经定义
                temp1_B[i] = temp1_B[i].substr(0,l)+temp1_B[i+1].substr(l,m-l);
                temp1_B[i+1] = temp1_B[i+1].substr(0,l)+temp;
            }
            //将交叉后的个体存入recombin_B
            for(int i=num2,j=0;i<N;i++,j++){
                recombin_B[i] = temp1_B[j];
            }
    
    
            //3.变异计算
            string varia_B[N];     //变异个体
            int varia_temp[N][m] ; //string不好操作,换成数组
            for(int i=0;i<N;i++){
                for(int j=0;j<m;j++){
                     varia_temp[i][j] = 0;
                }
            }
            for(int i=0;i<N;i++){
                for(int j=0;j<m;j++){
                     double rand_temp2 = rand()/double(RAND_MAX);  //取得0-1之间的浮点数
                     if(rand_temp2<=pm){
                        if((recombin_B[i][j]-'0')==1) varia_temp[i][j]==0;
                        else varia_temp[i][j]==1;
                     }
                     else varia_temp[i][j] =recombin_B[i][j]-'0';
                }
            }
            for(int i=0;i<N;i++){
                varia_B[i] = "";
                for(int j=0;j<m;j++){
                    if(varia_temp[i][j]==1) varia_B[i]+="1";
                    else varia_B[i]+="0";
                }
            }
    
    
            //4.选择下一代
            string select_B[2*N];      //选择的下一代的结果,P(t)+O1...On 从中选出最好的n个
            for(int i=0;i<N;i++){
                select_B[i] = B[i];
                select_B[N+i] = varia_B[i];
            }
            for(int i=0;i<2*N;i++){
                for(int j=i+1;j<2*N;j++){
                    if(Fit( get_x(select_B,j,a,b,m) )>Fit( get_x(select_B,i,a,b,m) )  ){
                        string temp_B = select_B[i];
                        select_B[i] = select_B[j];
                        select_B[j] = temp_B;
                    }
                }
            }
            //选择排好序的前N个
            for(int i=0;i<N;i++){
                B[i] = select_B[i];
            }
    
    
        }
    
        //输出结果
        double x_res = get_x(B,0,a,b,m);
        cout<<x_res<<endl<<bar_func(x_res)<<endl;
    
        system("pause");
        return 0;
    }
    

      

  • 相关阅读:
    阿里云乌班图16配置-PHP环境(包括mysql及apache安装)
    mysql主从复制跳过错误
    64位系统下powerdesigner15连接oracle odbc
    解决“指定的服务已经标记为删除”问题
    mysql系列-安装及服务启动
    数据缓存管理
    redis-在乌班图下设置自动启动
    redis-配置文件
    redis安装
    linux-用户建立及权限分配
  • 原文地址:https://www.cnblogs.com/liugl7/p/6948811.html
Copyright © 2020-2023  润新知