遗传算法---编程小试

利用遗传算法求解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;
}

  

 

posted on 2017-06-06 01:55  逸阳  阅读(241)  评论(0编辑  收藏  举报

导航