遗传算法的一个应用实例

很早以前在初等数学建模里碰到一个例子,给定n(n>=3)个顶点,求平面上的一个点或多个点,使得所有点连通,并且点到点的距离之和最小,书上给出了一个定理,就是当这些点与点的连线 的夹角都是120度时,可以证明 距离是最小的。当n=3时,只需一个点即可,并且可以通过几何的方法 轻易地找出,但是随着 n规模的增大,问题的复杂度将不可预测,而且没有一个有效地方法解决这个问题。恰巧当时学了遗传算法,就用它 求解。遗传算法可以在有限的时间内 找到一个最优近似解。

用遗传算法求解 ,必须解决三个问题,

第一 基因初始种类 我们说 好马才能生出 良驹 ,好的基因初始种类 可以缩短 基因的遗传代数 从而降低算法的复杂度。但是这个 好不能是主观上的好,即便是理论上的,也最好 对种类进行混搭 。

第二 最重要的就是基因的编码, 即设计一种较好的数据结构,这个数据结构需要尽量将每一个 独立因子分离出来,因子的数量不能太多,不然问题的复杂度就太大,也不能太少,这样就无法得到最优基因序列。具体可以参考多元统计分析里的因子分析理论,除此之外,基因在设计时还要考虑 便于衡量整个基因的好坏,因为我们要对基因进行优胜劣汰;

第三 基因的变异与交叉 也是十分重要的,变异是为了克服初始规模太小和最优因子序列遗失 从而避免过早收敛于局部最优解,这个变异的度必须把握好;交叉是为了获得最优因子序列重而获得最优基因。

本文以n=3为例 用遗传算法求解 ,这是最简单的一种情况。不需要 对基因,变异和交叉 进行严格设计。但是整个遗传算法的流程和思路是一样的,废话不多 上代码:

《遗传算法的一个应用实例》
《遗传算法的一个应用实例》
View Code

 1 #include<iostream>
2 #include<cstdio>
3 #include<cstdlib>
4 #include<cmath>
5 #include<ctime>
6 using namespace std;
7 //***************************************************************************
8 //This is a simple genetic algorithm implementation for function optimization
9 //参考书籍 《人工智能原理与应用》 金聪 清华大学出版社 2009
10 //Freeze 于2010 7 7
11
12 //Problem describing:assuming that there are three point in the plane xOy
13 //which located at O(0,0),P(12,0),Q(8,6).
14 //please find Point R to let W=5|RO|+4|RP|+3|RQ| reach the minimum value
15 //***************************************************************************
16 //Parametes setting
17 #define POPSIZE 200 //population size
18 #define MAXGENS 1000 //max number of generation
19 #define NVARS 2 //no of problem variables
20 #define PXOVER 0.75 //probalility of crossover
21 #define PMUTATION 0.15 //probalility of mutation
22 #define TRUE 1
23 #define FALSE 0
24 #define LBOUND 0
25 #define UBOUND 12
26 #define STOP 0.001
27 int generation; //current generation no
28 int cur_best; //best individual
29 double diff;
30 FILE *galog; //an output file
31 struct genotype
32 {
33 double gene[NVARS]; //a string of variables基因变量
34 double upper[NVARS]; //individual's variables upper bound 基因变量取值上确界
35 double lower[NVARS]; //individual's batiables lower bound 基因变量取值下确界
36 double fitness; //individual's fitness个体适应值
37 double rfitness; //relative fitness个体适应值占种群适应值比例
38 double cfitness; //curmulation fitness个体适应值的累加比例
39 };
40 struct genotype population[POPSIZE+1];
41 //population 当前种群 population[POPSIZE]用于存放个体最优值并假设最优个体能存活下去
42 //在某些遗传算法中最优值个体并不一定能够存活下去
43 struct genotype newpopulation[POPSIZE+1]; //new population replaces the old generation 子种群
44 /*Declaration of procedures used by the gentic algorithm*/
45 void initialize(void); //初始化函数
46 double randval(double,double); //随机函数
47 double funtion(double x1,double x2); //目标函数
48 void evaluate(void); //评价函数
49 void keep_the_best(void); //保留最优个体
50 void elitist(void); //当前种群与子代种群最优值比较
51 void select(void);
52 void crossover(void); //基因重组函数
53 void swap(double *,double *); //交换函数
54 void mutate(void); //基因突变函数
55 double report(void); //数据记录函数

《遗传算法的一个应用实例》
《遗传算法的一个应用实例》
View Code

  1 //**************************************************************************************
2 //Initializaton function:Initalizes the values of genes within the variables
3 //bounds.It also initializes all fitness values for each number of the population
4 //**************************************************************************************
5 void initialize(void)
6 {
7 int i,j;
8 for(i=0;i<NVARS;i++)
9 {
10 for(j=0;j<POPSIZE+1;j++)
11 {
12 if(!i)
13 {
14 population[j].fitness=0;
15 population[j].rfitness=0;
16 population[j].cfitness=0;
17 }
18 population[j].lower[i]=LBOUND;
19 population[j].upper[i]=UBOUND;
20 population[j].gene[i]=randval(population[j].lower[i],population[j].upper[i]);
21 }
22 }
23 }
24 //***************************************************************************
25 //Random value generator:generates a value within bounds
26 //***************************************************************************
27 double randval(double low,double high)
28 {
29 double val;
30 val=((double)(rand()%10000)/10000)*(high-low)+low;
31 return val;
32 }
33 //目标函数
34 double funtion(double x,double y)
35 {
36 double result1=sqrt(x*x+y*y)+sqrt((x-12)*(x-12)+y*y)+sqrt((x-8)*(x-8)+(y-6)*(y-6));
37 return result1;
38 }
39 //***************************************************************************
40 //Evaluation function:evaluate the individual's fitness.评价函数给出个体适应值
41 //Each time the function is changes,the code has to be recompl
42 //***************************************************************************
43 void evaluate(void)
44 {
45 int mem;
46 int i;
47 double x[NVARS];
48 for(mem=0;mem<POPSIZE;mem++)
49 {
50
51 for(i=0;i<NVARS;i++)
52 x[i]=population[mem].gene[i];
53 population[mem].fitness=funtion(x[0],x[1]);//将目标函数值作为适应值
54 }
55 }
56 //***************************************************************************************
57 //Keep_the_best function:This function keeps track of the best member of the population.
58 //找出种群中的个体最优值并将其移动到最后
59 //***************************************************************************************
60 void keep_the_best()
61 {
62 int mem;
63 int i;
64 cur_best=0;
65 for(mem=0;mem<POPSIZE;mem++)//找出最高适应值个体
66 {
67 if(population[mem].fitness<population[cur_best].fitness)
68 {
69 cur_best=mem;
70 }
71 }
72 //将最优个体复制至population[POSIZE]
73 if(population[cur_best].fitness<=population[POPSIZE].fitness||population[POPSIZE].fitness<1)//防止出现种群基因退化 故保留历史最优个体
74 {
75 population[POPSIZE].fitness=population[cur_best].fitness;
76 for(i=0;i<NVARS;i++)
77 population[POPSIZE].gene[i]=population[cur_best].gene[i];
78 }
79 }
80 //***************************************************************************
81 //Elitist function:The best member of the previous generation is stored as the
82 //last in the array.If the best individual from the new populatin is better
83 //than the best individual from the previous population ,then copy the best
84 //from the new population;else replace the worst individual from the current
85 //population with the best one from the previous generation.防止种群最优值退化
86 //***************************************************************************
87 void elitist()
88 {
89 int i;
90 double best,worst;//适应值
91 int best_mem,worst_mem;//序号
92 best_mem=worst_mem=0;
93 best=population[best_mem].fitness;//最高适应值初始化
94 worst=population[worst_mem].fitness;//最低适应值初始化
95 for(i=1;i<POPSIZE;i++)//找出最高和最低适应值 算法有待改进
96 {
97 if(population[i].fitness<best)
98 {
99 best=population[i].fitness;
100 best_mem=i;
101 }
102 if(population[i].fitness>worst)
103 {
104 worst=population[i].fitness;
105 worst_mem=i;
106 }
107 }
108 if(best<=population[POPSIZE].fitness)//赋值
109 {
110 for(i=0;i<NVARS;i++)
111 population[POPSIZE].gene[i]=population[best_mem].gene[i];
112 population[POPSIZE].fitness=population[best_mem].fitness;
113 }
114 else
115 {
116 for(i=0;i<NVARS;i++)
117 population[worst_mem].gene[i]=population[POPSIZE].gene[i];
118 population[worst_mem].fitness=population[POPSIZE].fitness;
119 }
120 }
121 //***************************************************************************
122 //Select function:Standard proportional selection for maximization problems
123 //incorporating elitist model--makes sure that the best member survives.筛选函数并产生子代
124 //***************************************************************************
125 void select(void)
126 {
127 int mem,i,j;
128 double sum=0;
129 double p;
130 for(mem=0;mem<POPSIZE;mem++)//所有适应值求和
131 {
132 sum+=population[mem].fitness;
133 }
134 for(mem=0;mem<POPSIZE;mem++)
135 {
136 population[mem].rfitness=population[mem].fitness/sum;//个人认为还不如建一个种群类 把sum看成类成员
137 }
138 population[0].cfitness=population[0].rfitness;
139 for(mem=1;mem<POPSIZE;mem++)
140 {
141 population[mem].cfitness=population[mem-1].cfitness+population[mem].rfitness;
142 }
143 for(i=0;i<POPSIZE;i++)
144 {
145 p=rand()%1000/1000.0;
146 if(p<population[0].cfitness)
147 {
148 newpopulation[i]=population[0];
149 }
150 else
151 {
152 for(j=0;j<POPSIZE;j++)
153 if(p>=population[j].cfitness&&p<population[j+1].cfitness)
154 newpopulation[i]=population[j+1];
155 }
156 }
157 for(i=0;i<POPSIZE;i++)//子代变父代
158 population[i]=newpopulation[i];
159 }

《遗传算法的一个应用实例》
《遗传算法的一个应用实例》
View Code

  1 //***************************************************************************
2 //Crossover:performs crossover of the selected parents.
3 //***************************************************************************
4 void Xover(int one,int two)//基因重组函数
5 {
6 int i;
7 int point;
8 if(NVARS>1)
9 {
10 if(NVARS==2)
11 point=1;
12 else
13 point=(rand()%(NVARS-1))+1;//两个都重组吗?
14 for(i=0;i<point;i++)//只有第一个基因发生重组有待改进
15 swap(&population[one].gene[i],&population[two].gene[i]);
16 }
17 }
18 //***************************************************************************
19 //Swapp: a swap procedure the helps in swappling 2 variables
20 //***************************************************************************
21 void swap(double *x,double *y)
22 {
23 double temp;
24 temp=*x;
25 *x=*y;
26 *y=temp;
27 }
28 //***************************************************************************
29 //Crossover function:select two parents that take part in the crossover.
30 //Implements a single point corssover.杂交函数
31 //***************************************************************************
32 void crossover(void)
33 {
34 int mem,one;
35 int first=0;
36 double x;
37 for(mem=0;mem<POPSIZE;++mem)
38 {
39 x=rand()%1000/1000.0;
40 if(x<PXOVER)
41 {
42 ++first;
43 if(first%2==0)//选择杂交的个体对 杂交有待改进 事实上往往是强者与强者杂交 这里没有考虑雌雄与杂交对象的选择
44 Xover(one,mem);
45 else
46 one=mem;
47 }
48 }
49 }
50 //***************************************************************************
51 //Mutation function:Random uniform mutation.a variable selected for mutation
52 //变异函数 事实基因的变异往往具有某种局部性
53 //is replaced by a random value between lower and upper bounds of the variables.
54 //***************************************************************************
55 void mutate(void)
56 {
57 int i,j;
58 double lbound,hbound;
59 double x;
60 for(i=0;i<POPSIZE;i++)
61 for(j=0;j<NVARS;j++)
62 {
63 x=rand()%1000/1000.0;
64 if(x<PMUTATION)
65 {
66 lbound=population[i].lower[j];
67 hbound=population[i].upper[j];
68 population[i].gene[j]=randval(lbound,hbound);
69 }
70 }
71 }
72 //***************************************************************************
73 //Report function:Reports progress of the simulation.
74 //***************************************************************************
75 double report(void)
76 {
77 int i;
78 double best_val;//种群内最优适应值
79 double avg;//平均个体适应值
80 //double stddev;
81 double sum_square;//种群内个体适应值平方和
82 //double square_sum;
83 double sum;//种群适应值
84 sum=0.0;
85 sum_square=0.0;
86 for(i=0;i<POPSIZE;i++)
87 {
88 sum+=population[i].fitness;
89 sum_square+=population[i].fitness*population[i].fitness;
90 }
91 avg=sum/(double)POPSIZE;
92 //square_sum=avg*avg*(double)POPSIZE;
93 //stddev=sqrt((sum_square-square_sum)/(POPSIZE-1));
94 best_val=population[POPSIZE].fitness;
95 fprintf(galog,"%6d %6.3f %6.3f %6.3f %6.3f %6.3f\n",generation,best_val,population[POPSIZE].gene[0],population[POPSIZE].gene[1],avg,sum);
96 return avg;
97 }
98 //***************************************************************************
99 //main function:Each generation involves selecting the best members,performing
100 //crossover & mutation and then evaluating the resulting population,until the
101 //terminating condition is satisfied.
102 //***************************************************************************
103 void main(void)
104 {
105 int i;
106 double temp;
107 double temp1;
108 if((galog=fopen("data.txt","w"))==NULL)
109 {
110 exit(1);
111 }
112 generation=1;
113 srand(time(NULL));
114 fprintf(galog,"number value x1 x2 avg sum_value\n");
115 printf("generation best average standard\n");
116 initialize();
117 evaluate();
118 keep_the_best();
119 temp=report();//记录,暂存上一代个体平均适应值
120 do
121 {
122 select();//筛选
123 crossover();//杂交
124 mutate();//变异
125 evaluate();//评价
126 keep_the_best();//elitist();
127 temp1=report();
128 diff=fabs(temp-temp1);
129 temp=temp1;
130 generation++;
131 }while(generation<MAXGENS&&diff>=STOP);
132 //fprintf(galog,"\n\n Simulation completed\n");
133 //fprintf(galog,"\n Best member:\n");
134 printf("\nBest member:\ngeneration:%d\n",generation);
135 for(i=0;i<NVARS;i++)
136 {
137 //fprintf(galog,"\n var(%d)=%3.3f",i,population[POPSIZE].gene[i]);
138 printf("X%d=%3.3f\n",i,population[POPSIZE].gene[i]);
139 }
140 //fprintf(galog,"\n\n Best fitness=%3.3f",population[POPSIZE].fitness);
141 fclose(galog);
142 printf("\nBest fitness=%3.3f\n",population[POPSIZE].fitness);
143 }

我相信对于那些没有 直接有效算法的最优值求解 使用遗传算法将是一个不错的选择。

    原文作者:遗传算法
    原文地址: https://www.cnblogs.com/2010Freeze/articles/2174417.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞