首页 技术 正文
技术 2022年11月23日
0 收藏 730 点赞 3,899 浏览 11785 个字

说明:在学习生活中,经常会遇到各种各样的最优问题,其中最常见的就是求某个多维(多个自变量)函数在各个自变量各取何值时的最大值或最小值;例如求函数 f(x) = (x-5)2+(y-6)2+(z-7)2 的最小值,当然,这个函数很简单,很容易看出来,该函数的最小值为0,分别在三个自变量取5,6,7时取得最小值。但日常学习中的函数都是很复杂的,就算通过大量的计算,也不一定能准确地算出目标值以及在何时取得该目标值,因此,本文介绍一种基于单目标的遗传算法来解决此类问题。

注意:由于封装函数较多,为了清晰,函数名一般为其英文名,因此比较长,强烈建议电脑阅读。

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

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

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 {
112 if(randgradient < gradient[0])
113 {
114 parent[j] = Initialpop[k];
115 }
116 }
117 else
118 {
119 if(randgradient >= gradient[k-1] && randgradient < gradient[k])
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

使用注意事项:

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

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

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

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

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

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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,031
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,520
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,368
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,148
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,781
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,862