1.遗传算法代码实现

a.第一部分为主函数

``````1 #include <iostream>
2 #include <genetic.h>
3 using namespace std;
4
5 int main()
6 {
7     Genetic M;
8     int Iteration = 0;
9     //种群及重要参数初始化
10     M.initiallize(M.Initialpop,Populationsize);
11     cout<<"\n\t\t\t\t  The Genetic Algrithm System\n"<<endl;
12     cout<<"\n\t\t\t\t\tThe Initial Pop:\n"<<endl;
13     cout<<setw(20)<<"x"<<setw(20)<<"y"<<setw(20)<<"z"<<setw(20)<<"Fitness"<<endl<<endl;
14     //获取种群适应度
15     M.getfitnessofpop(M.Initialpop,Populationsize);
16     //根据适应度排序
17     M.sortpopbyfitness(M.Initialpop,Populationsize);
18     //打印初始种群
19     M.printpop(M.Initialpop,Populationsize);
20     cout<<"\n\n\t\t\t\t\tThe Iteration Begins:\n"<<endl;
21     cout<<setw(20)<<"Iteration"<<setw(20)<<"x"<<setw(20)<<"y"<<setw(20)<<"z"<<setw(20)<<"Fitness"<<endl<<endl;
22     while(Iteration <= M.Iterationtimes)
23     {
24         //交叉
25         M.crossover(M.Initialpop,M.Offspring,Populationsize);
26         //求取种群适应度
27         M.getfitnessofpop(M.Offspring,Populationsize);
28         //根据适应度排序
29         M.sortpopbyfitness(M.Offspring,Populationsize);
30         //父子代结合
31         M.combinationpop(M.Initialpop,M.Offspring,M.Combinationpop,Populationsize);
32         //变异
33         M.mutation(M.Combinationpop,Populationsize*2);
34         //求取结合种群适应度
35         M.getfitnessofpop(M.Combinationpop,Populationsize*2);
36         //对结合种群排序
37         M.sortpopbyfitness(M.Combinationpop,Populationsize*2);
38         //选择较优个体
39         M.selectbestpop(M.Combinationpop,M.Initialpop,Populationsize);
40         //结果微调，精确算子
41         M.getAccurateResult(M.Initialpop,Populationsize);
42         //打印迭代过程中出现的最优个体
43         M.printbestindivil(M.Initialpop,Populationsize,Iteration);
44         Iteration++;
45     }
46     cout<<"\n\n"<<"The Last Population : \n"<<endl;
47     cout<<setw(20)<<"Iteration"<<setw(20)<<"x"<<setw(20)<<"y"<<setw(20)<<"z"<<setw(20)<<"Fitness"<<endl<<endl;
48     //打印最后一代的所有个体成员及其目标值
49     M.printpop(M.Initialpop,Populationsize);
50     cout<<"\n\n\n";
51     return 0;
52 }
53
54``````

View Code

b.第二部分为基因操作头文件

``````1 #ifndef GENETIC_H
2 #define GENETIC_H
3 #include <time.h>
4 #include <stdlib.h>
5 #include <iomanip>
6 #include <iostream>
7 #include <math.h>
8 using namespace std;
9 #define Populationsize 16
10 #define pi 3.1415926
11 #define Accurate 0.001
12 //精度越高要求迭代次数越大
13
14 class Genetic
15 {
16 public:
17     Genetic();
18     typedef struct Individual
19     {
20         double x;
21         double y;
22         double z;
23         double fitness;
24     }Individuals;
25     Individuals Initialpop[Populationsize];
26     Individuals Offspring[Populationsize];
27     Individuals Combinationpop[Populationsize*2];
28     Individuals Bestindividual;
29     double crossoverability;
30     double mutationproability;
31     double downlimit;
32     double uplimit;
33     double downlimit1;
34     double uplimit1;
35     double downlimit2;
36     double uplimit2;
37     int Iterationtimes;
38
39     void initiallize(Individuals *Initialpop,int Populationsiz);
40     void printpop(Individuals *Initialpop,int Populationsiz);
41     double getfitnessofindiv(double x,double y,double z);
42     void getfitnessofpop(Individuals *Initialpop,int Populationsiz);
43     void sortpopbyfitness(Individuals *Initialpop,int Populationsiz);
44     void crossover(Individuals *Initialpop,Individuals *offspring,int Populationsiz);
45     void combinationpop(Individuals *Initialpop,Individuals *offspring,Individuals* Combinationpop,int populationsize);
46     void mutation(Individuals *Initialpop,int population);
47     void selectbestpop(Individuals* Combinationpo,Individuals *Initialpop,int population);
48     void printbestindivil(Individuals* Initialpop,int populationsize, int Iteration);
49     void getAccurateResult(Individuals* Initialpop,int population);
50 };
51
52 #endif // GENETIC_H
53``````

View Code

c.第三部分为基因操作头文件相应的 cpp 文件

``````1 #include "genetic.h"
2
3 Genetic::Genetic()
4 {
5
6 }
7 void Genetic::initiallize(Genetic::Individuals *Initialpop, int Populationsiz)
8 {
9     cout<<"Welcome To The Genetic Algrithm System......\n";
10     cout<<"\nPls Follow The Steps To Complete Your Compution.....\n\n";
11     cout<<"\nStep 1: Pls Make Sure The Function Have Been Modefied.....\n";
12     cout<<"\nStep 2: Pls Input The Downlimit Of First Variation :";
13     cin>>downlimit;
14     cout<<"\nStep 3: Pls Input The Uplimit Of First Variation :";
15     cin>>uplimit;
16     cout<<"\nStep 4: Pls Input The Downlimit Of Second Variation :";
17     cin>>downlimit1;
18     cout<<"\nStep 5: Pls Input The Uplimit Of Second Variation :";
19     cin>>uplimit1;
20     cout<<"\nStep 6: Pls Input The Downlimit Of Third Variation :";
21     cin>>downlimit2;
22     cout<<"\nStep 7: Pls Input The Uplimit Of Third Variation :";
23     cin>>uplimit2;
24     cout<<"\nStep 8: Pls Input The Max Iteration Times Of The Caculate:";
25     cin>>Iterationtimes;
26     srand(time(NULL));
27     crossoverability = 0.8;
28     mutationproability = 0.1;
29     for(int i=0; i<Populationsiz; i++)
30     {
31         Initialpop[i].x = downlimit + (rand()%50)/50.0*(uplimit-downlimit);
32         Initialpop[i].y = downlimit1 + (rand()%50)/50.0*(uplimit1-downlimit1);
33         Initialpop[i].z = downlimit2 + (rand()%50)/50.0*(uplimit2-downlimit2);
34     }
35 }
36
37 void Genetic::printpop(Genetic::Individuals *Initialpop, int Populationsiz)
38 {
39     for(int i =0;i<Populationsiz;i++)
40     {
41         cout<<setw(20)<<setprecision(5)<<Initialpop[i].x<<setw(20)<<setprecision(5)
42            <<Initialpop[i].y<<setw(20)<<setprecision(5)<<Initialpop[i].z<<setw(20)
43           <<fixed<<setprecision(7)<<Initialpop[i].fitness<<endl;
44     }
45 }
46
47 double Genetic::getfitnessofindiv(double x, double y, double z)
48 {
49     double result;
50     result = -(x+12)*(x+12)-(y+7)*(y+7)-(z+10)*(z+10);
51     return result;
52 }
53
54 void Genetic::getfitnessofpop(Genetic::Individuals *Initialpop, int Populationsiz)
55 {
56     for(int i = 0;i<Populationsiz;i++)
57     {
58         Initialpop[i].fitness = getfitnessofindiv(Initialpop[i].x,Initialpop[i].y,Initialpop[i].z);
59     }
60 }
61
62 void Genetic::sortpopbyfitness(Genetic::Individuals *Initialpop, int Populationsiz)
63 {
64     for(int i = 0;i<Populationsiz;i++)
65     {
66         int idx = i;
67         for(int j = i+1;j<Populationsiz;j++)
68         {
69             if(Initialpop[idx].fitness > Initialpop[j].fitness)
70                 idx = j;
71         }
72         if(idx != i)
73         {
74             Individual temp = Initialpop[i];
75             Initialpop[i] = Initialpop[idx];
76             Initialpop[idx] = temp;
77         }
78     }
79     Bestindividual = Initialpop[0];
80 }
81
82 void Genetic::crossover(Individuals *Initialpop,Individuals *offspring, int Populationsiz)
83 {
84     for(int i = 1;i<=Populationsiz;i++)
85     {
86         //保证适值为正
87         Initialpop[Populationsiz-i].fitness += -Initialpop[0].fitness;
88     }
89     srand(time(NULL));
90     Individuals parent[2];
91     double temp = 0;
92     double totalfitness = 0;
93     double gradient[Populationsiz] = {0};
94     for(int i = 0;i<Populationsiz;i++)
95     {
96         totalfitness += Initialpop[i].fitness;
97     }
98     for(int i = 0;i<Populationsiz;i++)
99     {
100         temp += Initialpop[i].fitness;
101         gradient[i] = temp/totalfitness;
102     }
103     for(int i = 0;i<Populationsiz/2;i++)
104     {
105         for(int j = 0;j<2;j++)
106         {
107             double randgradient = rand()%1000/1000.0;
108             for(int k = 0;k<Populationsiz;k++)
109             {
110                 if(k == 0)
111                 {
113                     {
114                         parent[j] = Initialpop[k];
115                     }
116                 }
117                 else
118                 {
120                     {
121                         parent[j] = Initialpop[k];
122                     }
123                 }
124             }
125         }
126         double Probability = rand()%1000/1000.0;
127         if(Probability < crossoverability)
128         {
129             double b = rand()%100/100.0;
130             if(b <= 0.5)
131             {
132                 double a = pow(2*b,1/21.0);
133                 offspring[2*i].x = ((1+a)*parent[0].x+(1-a)*parent[1].x)/2.0;
134                 offspring[2*i+1].x = ((1-a)*parent[0].x+(1+a)*parent[1].x)/2.0;
135                 offspring[2*i].y = ((1+a)*parent[0].y+(1-a)*parent[1].y)/2.0;
136                 offspring[2*i+1].y = ((1-a)*parent[0].y+(1+a)*parent[1].y)/2.0;
137                 offspring[2*i].z = ((1+a)*parent[0].y+(1-a)*parent[1].z)/2.0;
138                 offspring[2*i+1].z = ((1-a)*parent[0].y+(1+a)*parent[1].z)/2.0;
139
140                 if(offspring[2*i].x < downlimit || offspring[2*i].x > uplimit
141                         || offspring[2*i+1].x < downlimit || offspring[2*i+1].x > uplimit
142                         || offspring[2*i].y < downlimit1 || offspring[2*i].y > uplimit1
143                         || offspring[2*i+1].y < downlimit1 || offspring[2*i+1].y > uplimit1
144                         || offspring[2*i].z < downlimit2 || offspring[2*i].z > uplimit2
145                         || offspring[2*i+1].z < downlimit2 || offspring[2*i+1].z > uplimit2)
146                 {
147                     i--;
148                 }
149
150             }
151             else
152             {
153                 double a = pow(2*(1-b),-1/21.0);
154                 offspring[2*i].x = ((1+a)*parent[0].x+(1-a)*parent[1].x)/2.0;
155                 offspring[2*i+1].x = ((1-a)*parent[0].x+(1+a)*parent[1].x)/2.0;
156                 offspring[2*i].y = ((1+a)*parent[0].y+(1-a)*parent[1].y)/2.0;
157                 offspring[2*i+1].y = ((1-a)*parent[0].y+(1+a)*parent[1].y)/2.0;
158                 offspring[2*i].z = ((1+a)*parent[0].y+(1-a)*parent[1].z)/2.0;
159                 offspring[2*i+1].z = ((1-a)*parent[0].y+(1+a)*parent[1].z)/2.0;
160
161                 if(offspring[2*i].x < downlimit || offspring[2*i].x > uplimit
162                         || offspring[2*i+1].x < downlimit || offspring[2*i+1].x > uplimit
163                         || offspring[2*i].y < downlimit1 || offspring[2*i].y > uplimit1
164                         || offspring[2*i+1].y < downlimit1 || offspring[2*i+1].y > uplimit1
165                         || offspring[2*i].z < downlimit2 || offspring[2*i].z > uplimit2
166                         || offspring[2*i+1].z < downlimit2 || offspring[2*i+1].z > uplimit2)
167                 {
168                     i--;
169                 }
170             }
171         }
172         else
173         {
174             offspring[2*i].x = downlimit + (rand()%50)/50.0*(uplimit-downlimit);
175             offspring[2*i].y = downlimit1 + (rand()%50)/50.0*(uplimit1-downlimit1);
176             offspring[2*i].z = downlimit2 + (rand()%50)/50.0*(uplimit2-downlimit2);
177
178             offspring[2*i+1].x = downlimit + (rand()%50)/50.0*(uplimit-downlimit);
179             offspring[2*i+1].y = downlimit1 + (rand()%50)/50.0*(uplimit1-downlimit1);
180             offspring[2*i+1].z = downlimit2 + (rand()%50)/50.0*(uplimit2-downlimit2);
181         }
182     }
183 }
184
185 void Genetic::combinationpop(Individuals *Initialpop,Individuals *offspring,Individuals *Combinationpop,int populationsize)
186 {
187     for(int i = 0;i<populationsize*2;i++)
188     {
189         if(i < populationsize)
190             Combinationpop[i] = Initialpop[i];
191         else
192             Combinationpop[i] = offspring[i-populationsize];
193     }
194 }
195
196 void Genetic::mutation(Genetic::Individuals *Initialpop, int population)
197 {
198     srand(time(NULL));
199     for(int i = 0;i<population;i++)
200     {
201         double a = rand()%100/100.0;
202         if(a <= mutationproability)
203         {
204             Initialpop[i].x = downlimit + (rand()%50)/50.0*(uplimit-downlimit);
205             Initialpop[i].y = downlimit1 + (rand()%50)/50.0*(uplimit1-downlimit1);
206             Initialpop[i].z = downlimit2 + (rand()%50)/50.0*(uplimit2-downlimit2);
207         }
208     }
209 }
210
211 void Genetic::selectbestpop(Individuals *Combinationpo,Individuals *Initialpop, int population)
212 {
213     for(int i = 0;i<population;i++)
214         Initialpop[i] = Combinationpo[population+i];
215 }
216
217 void Genetic::printbestindivil(Genetic::Individuals *Initialpop, int populationsize,int Iteration)
218 {
219     cout<<"\r";
220     cout<<setw(20)<<Iteration<<setw(20)<<Initialpop[populationsize-1].x<<setw(20)
221        <<Initialpop[populationsize-1].y<<setw(20)<<Initialpop[populationsize-1].z
222       <<setw(20)<<Initialpop[populationsize-1].fitness;
223 }
224
225 void Genetic::getAccurateResult(Genetic::Individuals *Initialpop, int population)
226 {
227     for(int j = 0;j<population;j++)
228     {
229         if(getfitnessofindiv(Initialpop[j].x*(1+Accurate),Initialpop[j].y,Initialpop[j].z)
230                 > Initialpop[j].fitness && Initialpop[j].x*(1+Accurate) <= uplimit &&
231                 Initialpop[j].x*(1+Accurate) >= downlimit)
232             Initialpop[j].x = Initialpop[j].x*(1+Accurate);
233         if(getfitnessofindiv(Initialpop[j].x*(1-Accurate),Initialpop[j].y,Initialpop[j].z)
234                 > Initialpop[j].fitness && Initialpop[j].x*(1-Accurate) >= downlimit &&
235                 Initialpop[j].x*(1-Accurate) <= uplimit)
236             Initialpop[j].x = Initialpop[j].x*(1-Accurate);
237         if(getfitnessofindiv(Initialpop[j].x,Initialpop[j].y*(1+Accurate),Initialpop[j].z)
238                 > Initialpop[j].fitness && Initialpop[j].y*(1+Accurate) <= uplimit1 &&
239                 Initialpop[j].y*(1+Accurate) >= downlimit1)
240             Initialpop[j].y = Initialpop[j].y*(1+Accurate);
241         if(getfitnessofindiv(Initialpop[j].x,Initialpop[j].y*(1-Accurate),Initialpop[j].z)
242                 > Initialpop[j].fitness && Initialpop[j].y*(1-Accurate) >= downlimit1 &&
243                 Initialpop[j].y*(1-Accurate) <= uplimit1)
244             Initialpop[j].y = Initialpop[j].y*(1-Accurate);
245         if(getfitnessofindiv(Initialpop[j].x,Initialpop[j].y,Initialpop[j].z*(1+Accurate))
246                 > Initialpop[j].fitness && Initialpop[j].z*(1+Accurate) <= uplimit2 &&
247                 Initialpop[j].z*(1+Accurate) >= downlimit2)
248             Initialpop[j].z = Initialpop[j].z*(1+Accurate);
249         if(getfitnessofindiv(Initialpop[j].x,Initialpop[j].y,Initialpop[j].z*(1-Accurate))
250                 > Initialpop[j].fitness && Initialpop[j].z*(1-Accurate) >= downlimit2 &&
251                 Initialpop[j].z*(1-Accurate) <= uplimit2)
252             Initialpop[j].z = Initialpop[j].z*(1-Accurate);
253
254     }
255
256 }
257
258``````

View Code

a.根据具体的目标函数修改评价函数方程，

b.根据具体的自变量的范围及其维数来设计初始化函数及相关的函数。

c.Accurate 参数用于当目标函数趋于稳定状态时的优化，即探测此时自变量该精度变化范围内的目标函数变化情况，从而获得更为优越的目标值。应注意的是，当要求精度越高时，该参数要求尽量小，同时迭代次数应该尽可能地高。

d.本例中涉及一个三维的单目标测试函数，使用源代码直接按照提示步骤输入相应的各个变量上下限及迭代次数即可。

★★★基于C++改进的单目标遗传算法实现界面★★★★

★★★   测试函数最大值为 零   ★★★