遗传算法
Posted 光何
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了遗传算法相关的知识,希望对你有一定的参考价值。
关键字:人工智能,遗传算法,进化计算
Production system
Abstract: Genetic algorithm (geneticalgorithms, GA) is mimic biological genetics and natural selection mechanism, the random global search algorithm of adaptive (Holland, Mr Rand) and the nature of "natural selection" and "evolution" Darwin (Charles Darwin) and biological genetic theory (Gregor Johann Mendel in fruit, John Mendel) theory synthetically, through artificial means the constructed a kind of random adaptive global optimization search algorithm, is a kind of mathematical simulation of biological evolution process, is the most important form of evolutionary computation. Genetic algorithm (ga) for those who are hard to find the problem of traditional mathematical model points out a solution. Evolutionary computation and genetic algorithm is used to refer to some knowledge of the biological sciences, this also reflected the characteristics of artificial intelligence in the interdisciplinary. This paper mainly discusses the computer science and technology under the junior in professional class "artificial intelligence" sixth experiment algorithm.
Keywords: Artificial intelligence, genetic algorithms, evolutionary computation
1,编码与译码
借用生物的术语,把位串形式的解的编码表示叫染色体或基因型(基因表达),或叫个体。原问题结构即一个染色体解码后所对应的解称为表现型。编码空间也称为基因型空间或搜索空间。解空间也称为表现型空间。
进化算法不是直接作用在问题的解空间上,而是交替地作用在编码空间和解空间上。在编码空间对个体进行遗传操作,在解空间对问题的解进行评估。
2,适应度函数
为了体现染色体的适应能力,引入了对问题中的每一个染色体都能进行度量的函数,叫适应度函数。通过适应度函数来决定染色体的优、劣程度,它体现了自然进化中的优胜劣汰原则。对优化问题,适应度函数就是目标函数。TSP的目标是路径总长度为最短,路径总长度的倒数就可以为TSP的适应度函数。
其中wn+1= w1。适应度函数要有效反映每一个染色体与问题的最优解染色体之间的差距,一个染色体与问题的最优解染色体之间的差距小,则对应的适应度函数值之差就小,否则就大。适应度函数的取值大小与求解问题对象的意义有很大的关系。
3,遗传操作
1)计算各染色体适应度值
2)累计所有染色体适应度值(或选择概率),记录每个个体的适应度累加值(或概率累加值)
3) 产生一个随机数 r,0< r < sumN(或0< r < 1)
4)若sumk-1< r £ sumk(或qk-1< r £ qk ),则选择第k个个体进入交配池。
5) 重复(3)和(4),直到获得足够的染色体。
4,程序流程
一般遗传算法的主要步骤如下:
(1) 随机产生一个由确定长度的特征字符串组成的初始群体。
(2) 对该字符串群体迭代的执行下面的步①和② ,直到满足停止标准:
①计算群体中每个个体字符串的适应值;
②应用选择、交叉和变异等遗传算子产生下一代群体。
(3) 把在后代中出现的最好的个体字符串指定为遗传算法的执行结果,这个结果可以表示问题的一个解。
5,问题解析
6,程序设计
1 #include<iostream> 2 #include<cstdlib> 3 #include<ctime> 4 #include<cmath> 5 #include<iomanip> 6 using namespace std; 7 8 const int NUM=1000; //最大迭代次数 9 const int POP_SIZE=50; //种群规模:个体数量 10 const int GENE=33; //每个个体染色体个数 11 const int GB1=18; //染色体手段基因片段(二进制) 12 const int GB2=15; //染色体末端基因片段(二进制) 13 const int GD=6; //十进制保留小数点位数 14 const double PI=3.1415926; 15 16 void initialize(int v[][GENE]) //初始化群体 17 { 18 int ii,ij; 19 srand(time(0)); 20 cout<<"基因初始化:"<<endl; 21 for(ii=0;ii<POP_SIZE;ii++) 22 { 23 cout<<endl<<"个体"<<setw(2)<<ii+1<<"基因型 "; 24 for(ij=0;ij<GENE;ij++) 25 { 26 v[ii][ij]=2*rand()/RAND_MAX; 27 cout<<v[ii][ij]; 28 } 29 } 30 cout<<endl; 31 } 32 33 void evaluation(int v[][GENE],double eval[]) //评估函数 34 { 35 int ii,ij; 36 double x1,x2; 37 for(ii=0;ii<POP_SIZE;ii++) 38 { 39 x1=x2=0; 40 for(ij=0;ij<GB1;ij++) //二进制片段转为十进制编码 41 { 42 x1+=v[ii][ij]*pow(2,(GB1-(ij+1))); 43 } 44 for(ij=GB1;ij<GENE;ij++) 45 { 46 x2+=v[ii][ij]*pow(2,(GENE-(ij+1))); 47 } 48 x1=-3.0+x1*(12.1-(-3.0))/(pow(2,GB1)-1); //十进制编码转为十进制值 49 x2=4.1+x2*(5.8-4.1)/(pow(2,GB2)-1); 50 eval[ii]=21.5+x1*sin(4*PI*x1)+x2*sin(20*PI*x2); 51 } 52 } 53 54 int best_eval(double eval[]) //找出每代中最优秀个体基因值 55 { 56 int ii,cursor=0; 57 for(ii=0;ii<POP_SIZE;ii++) 58 { 59 if(eval[ii]>eval[cursor]) 60 { 61 cursor=ii; 62 } 63 } 64 return cursor; 65 } 66 67 int worst_eval(double eval[]) //找出每代中最差个体基因值 68 { 69 int ii,cursor=0; 70 for(ii=0;ii<POP_SIZE;ii++) 71 { 72 if(eval[ii]<eval[cursor]) 73 { 74 cursor=ii; 75 } 76 } 77 return cursor; 78 } 79 80 void selection(double eval[],int v[][GENE],int v_next[][GENE]) 81 { 82 int ii,ij,ik; 83 double value; 84 double p[POP_SIZE]; //选择概率 85 double pp[POP_SIZE]={0}; //累积概率 86 double total_value=0; 87 for(ii=0;ii<POP_SIZE;ii++) 88 { 89 total_value+=eval[ii]; 90 } 91 for(ii=0;ii<POP_SIZE;ii++) 92 { 93 p[ii]=eval[ii]/total_value; 94 } 95 pp[0]=p[0]; 96 for(ii=1;ii<POP_SIZE;ii++) 97 { 98 pp[ii]=pp[ii-1]+p[ii]; 99 } 100 for(ii=0;ii<POP_SIZE;ii++) //对于每个次代个体的基因型 101 { 102 value=(double)rand()/RAND_MAX; //转动轮盘 103 for(ij=0;ij<POP_SIZE;ij++) //搜索命中区域 104 { 105 if(value<pp[ij]) //找到后复制、跳出 106 { 107 for(ik=0;ik<GENE;ik++) 108 { 109 v_next[ii][ik]=v[ij][ik]; 110 } 111 break; 112 } 113 } 114 } 115 } 116 117 void crossover(int v[][GENE]) 118 { 119 int ii,ij,ik; 120 double p=0.8,value1; 121 int n=0,tmp,value2; 122 int cursor[POP_SIZE]={-1}; //被选中的染色体下标 123 for(ii=0;ii<POP_SIZE;ii++) //找被选中的染色体下标 124 { 125 value1=(double)rand()/RAND_MAX; 126 if(value1<p) 127 { 128 cursor[n++]=ii; 129 } 130 } 131 for(ii=0;ii<n;ii+=2) //两两配对,进行交叉 132 { 133 value2=(int)(GENE-1)*rand()/RAND_MAX+1; 134 for(ij=value2;ij<GENE;ij++) 135 { 136 tmp=v[cursor[ii]][ij]; 137 v[cursor[ii]][ij]=v[cursor[ii+1]][ij]; 138 v[cursor[ii+1]][ij]=tmp; 139 } 140 } 141 } 142 143 void mutation(int v[][GENE]) 144 { 145 int ii,ij,ik; 146 int sum,gene; //基因变异数目 147 double pm=0.01; //变异概率 148 sum=(int)(POP_SIZE*GENE*pm)+1; 149 for(ii=0;ii<sum;ii++) 150 { 151 gene=(int)(POP_SIZE*GENE)*rand()/RAND_MAX; 152 ij=gene/(POP_SIZE*GENE); 153 ik=gene%(POP_SIZE*GENE); 154 v[ij][ik]=1-v[ij][ik]; 155 } 156 } 157 158 int main(int argc,char **argv) 159 { 160 int ii,ij,ik,max=0; 161 int v[POP_SIZE][GENE]; //本代群体基因库 162 int v_next[POP_SIZE][GENE]; //次代群体基因库 163 double eval[POP_SIZE]; //本代群体评估值 164 double eval_next[POP_SIZE]; //次代群体评估值 165 int best_cursor; //本代最优个体适值下标 166 int best_next_cursor; //次代最优个体适值下标 167 int worst_next_cursor; //次代最差个体适值下标 168 int best_gene[GENE]; //本代最优个体基因型 169 initialize(v); 170 for(ii=0;ii<NUM&&max<50;ii++) 171 { 172 evaluation(v,eval); //本代基因评估 173 best_cursor=best_eval(eval); //本代最优个体 174 cout<<endl<<"第"<<setw(3)<<ii+1<<"代最优基因:"; 175 for(ij=0;ij<GENE;ij++) //保存本代最优基因 176 { 177 best_gene[ij]=v[best_cursor][ij]; 178 cout<<best_gene[ij]; 179 } 180 cout<<" 适值:"<<eval[best_cursor]; 181 selection(eval,v,v_next); //选择 182 crossover(v_next); //交叉 183 mutation(v_next); //变异 184 evaluation(v_next,eval_next); 185 worst_next_cursor=worst_eval(eval_next); 186 for(ij=0;ij<GENE;ij++) 187 { 188 v_next[worst_next_cursor][ij]=best_gene[ij]; 189 } 190 evaluation(v_next,eval_next); 191 best_next_cursor=best_eval(eval_next); 192 eval[best_cursor]==eval_next[best_next_cursor]?max++:max=0; 193 for(ij=0;ij<POP_SIZE;ij++) 194 { 195 for(ik=0;ik<GENE;ik++) 196 { 197 v[ij][ik]=v_next[ij][ik]; 198 } 199 } 200 } 201 cout<<endl<<"最优基因适值为:"<<eval[best_cursor]<<endl; 202 cout<<"迭代次数为:"<<ii<<endl; 203 system("pause"); 204 return 0; 205 } 206 /* 207 **本题最优值是38.818208 208 209 (1) 初始化群体; 210 (2) 计算群体上每个个体的适应度值; 211 (3) 按由个体适应度值所决定的某个规则选 212 择将进入下一代的个体; 213 (4) 按概率Pc进行交叉操作; 214 (5) 按概率Pm进行突变操作; 215 (6) 若没有满足某种停止条件,则转第(2)步, 216 否则进入下一步。 217 (7) 输出群体中适应度值最优的染色体作为问题的 218 满意解或最优解。 219 */
以上是关于遗传算法的主要内容,如果未能解决你的问题,请参考以下文章