说明:在学习生活中,经常会遇到各种各样的最优问题,其中最常见的就是求某个多维(多个自变量)函数在各个自变量各取何值时的最大值或最小值;例如求函数 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++改进的单目标遗传算法实现界面★★★★

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

(C/C++学习)19.单目标遗传算法的C程序实现的更多相关文章

  1. (C/C++学习)20.基于C++改进的单目标遗传算法

    说明:在学习生活中,经常会遇到各种各样的最优问题,其中最常见的就是求某个多维(多个自变量)函数在各个自变量各取何值时的最大值或最小值:例如求函数 f(x) = (x-5)2+(y-6)2+(z-7)2 ...

  2. Video Target Tracking Based on Online Learning—TLD单目标跟踪算法详解

    视频目标跟踪问题分析         视频跟踪技术的主要目的是从复杂多变的的背景环境中准确提取相关的目标特征,准确地识别出跟踪目标,并且对目标的位置和姿态等信息精确地定位,为后续目标物体行为分析提供足 ...

  3. OpenCV 学习笔记 07 目标检测与识别

    目标检测与识别是计算机视觉中最常见的挑战之一.属于高级主题. 本章节将扩展目标检测的概念,首先探讨人脸识别技术,然后将该技术应用到显示生活中的各种目标检测. 1 目标检测与识别技术 为了与OpenCV ...

  4. 检索(retrieval && search )-单目标-多目标跟踪-MTMC Tracking和 ReID

    跨摄像头多目标跟踪(Multi-Target Multi-Camera Tracking, MTMC Tracking) 跨摄像头多目标跟踪(Multi-Target Multi-Camera Tra ...

  5. ECCV 2018 | 旷视科技提出GridFace:通过学习局部单应变换实现人脸校正

    全球计算机视觉三大顶会之一 ECCV 2018(European Conference on Computer Vision)即将于 9 月 8 -14 日在德国慕尼黑拉开帷幕,旷视科技有多篇论文被此 ...

  6. (转)Unity Cinemachine插件,实现单目标和多目标之间切换

    Unity Cinemachine插件学习笔记,实现单目标和多目标之间切换*版本要求Unity2017.1及以上. 参考资料: [官方] Unity 2017.1正式版发布 Cinemachine插件 ...

  7. VUE2 第六天学习--- vue单文件项目构建

    阅读目录 VUE2 第六天学习--- vue单文件项目构建 回到顶部 VUE2 第六天学习--- vue单文件项目构建 VUE单文件组件在Vue项目中,然后使用 new Vue({el: '#cont ...

  8. 制定一个学习liunx的目标

        制定一个学习liunx的目标       学习目标方法 1.在这五个月的学习时间里,制定一套自己的学习方式. 2.养成做笔记以及写博客的习惯 . 3.坚持上课前预习,自习时间总结 . 4.紧跟 ...

  9. Spring+SpringMVC+MyBatis深入学习及搭建(十二)——SpringMVC入门程序(一)

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6999743.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十一)——S ...

随机推荐

  1. Vijos 1523 贪吃的九头龙 【树形DP】

    贪吃的九头龙 背景 安徽省芜湖市第二十七中学测试题 NOI 2002 贪吃的九头龙(dragon) Description:OfficialData:OfficialProgram:Converted ...

  2. 安装linux系统-CentOS-6.8-x86_64-minimal.iso

    1: 2: 3:单击[Next]继续安装. 4:安装语言,选择[Chinese(Simplified)(中文(简体))]菜单,单击[Next]继续. 5:系统键盘,选择[美国英语式]菜单,单击[下一步 ...

  3. CollapsingToolbarLayout Toolbar的title覆盖问题

    CollapsingToolbarLayout 里: 1 2 app:titleEnabled="true" app:title="Hello" Toolbar ...

  4. Create schema error (unknown database schema '')

    Andrey Devyatka 4 years ago Permalink Raw Message Hi,Please tell me, can I use the static library in ...

  5. 杂项-DB:Druid

    ylbtech-杂项-DB:Druid Apache Druid (incubating) is a high performance analytics data store for event-d ...

  6. 百度上传组件 WebUploader

    WebUploader http://fex.baidu.com/webuploader/doc/index.html WebUploader API 文档详细解读 源码以及示例:https://gi ...

  7. bzoj 2442: [Usaco2011 Open]修剪草坪【单调栈】

    设f[i]为i不选的最小损失,转移是f[i]=f[j]+e[i[(i-j-1<=k) 因为f是单调不降的,所以f[j]显然越靠右越好因为i-j-1<=k的限制,所以单调栈需要弹栈 #inc ...

  8. bzoj 1710: [Usaco2007 Open]Cheappal 廉价回文【区间dp】

    只要发现添加一个字符和删除一个字符是等价的,就是挺裸的区间dp了 因为在当前位置加上一个字符x就相当于在他的对称位置删掉字符x,所以只要考虑删除即可,删除费用是添加和删除取min 设f[i][j]为从 ...

  9. MySQL-ProxySQL中间件(二)| Admin Schemas介绍

    目录     MySQL-ProxySQL中间件(一)| ProxySQL基本概念: https://www.cnblogs.com/SQLServer2012/p/10972593.html     ...

  10. Laravel5.1学习笔记23 Eloquent 序列化

    Eloquent: Serialization Introduction Basic Usage Hiding Attributes From JSON Appending Values To JSO ...