遗传算法
2016-04-22 17:24
441 查看
遗传算法是解决搜索问题的一种通用算法。
模拟自然界优胜劣汰的进化现象,把搜索问题转化为遗传问题,把可能的解转为成一个向量——染色体,向量的每个元素称为基因。通过不断计算各染色体的适应值,选择最好的染色体,获得最优解。
基本概念 (以下均以二进制串 a=<1000101110110101000111> 为例)
1. 遗传:子代和父代具有相同或相似的性状,保证物种的稳定性;
2. 变异:子代与父代,子代不同个体之间总有差异,是生命多样性的根源;
3. 生存斗争和适者生存:具有适应性变异的个体被保留,不具适应性变异的个体被淘汰。
自然选择过程是长期的、缓慢的、连续的过程。
4. 个体与种群
● 个体就是模拟生物个体而对问题中的对象(一般就是问题的解)的一种称呼,一个个体也就是搜索空间中的一个点。
● 种群就是模拟生物种群而由若干个体组成的群体, 它一般是整个搜索空间的一个很小的子集。
5. 适应度与适应度函数
● 适应度就是借鉴生物个体对环境的适应程度,而对问题中的个体对象所设计的表征其优劣的一种测度。
● 适应度函数就是问题中的全体个体与其适应度之间的一个对应关系。它一般是一个实值函数。该函数就是遗传算法中指导搜索的评价函数,数值越接近目标值则说明适应度越高。
6. 染色体与基因
● 染色体(chromosome)就是问题中个体的某种字符串形式的编码表示。字符串中的字符也就称为基因。
7. 遗传操作
亦称遗传算子(genetic operator),就是关于染色体的运算。遗传算法中有三种遗传操作:
● 选择 (selection)
● 交叉(crossover,亦称交换、交配或杂交)
● 变异(mutation,亦称突变)
现在写个简单的例子:设 f(x) = -x2 + 2x + 0.5,求 max f(x), x在[-1, 2]之间。
对于二进制串 a=<1000101110110101000111> ;
1.先将其转为十进制数:ve=2288967
2.将其转化为[-1,2]内的实数为:
X=-1+ve*(2-(-1))/((2^22)-1)=0.631797
3.随机的产生一个初始群体(这里假设初始群体的个体数为 4)
pop1={
<1101011101001100011110>, % a1
<1000011001010001000010>, % a2
<0001100111010110000000>, % a3
<0110101001101110010101>} % a4
4.转化成 [-1, 2] 之间的十进制数即为
pop1={ 1.523032,0.574022,-0.697235,0.247238}
5.定义适应函数和求适应值
最后假设得到适应值:
g(pop1)={2.226437,2.318543, 0,1.933350}
6.算出入选下一代的概率:
p(pop1)=g(pop1)/sum(g(pop1))
={0.343675, 0.357892, 0, 0.298433}
7.产生种群
newpop1={
<110101110 1001100011110>, % a1
<100001100 1010001000010>, % a2
<10000110010100 01000010>, % a2
<01101010011011 10010101>} % a4
8.交叉:
将第七步的加粗部分交换,(a1与a2,a3与a4)得到如下结果:
<1101011101010001000010>, % a1
<1000011001001100011110>, % a2
<10000110 0 1010010010101>, % a2
<0110101001101101000010>} % a4
9.变异:将a3中加粗基因变异:
<1101011101010001000010>, % a1
<1000011001001100011110>, % a2
<10000110 1 1010010010101>, % a2
<0110101001101101000010>} % a4
10.终止:我们可以采用遗传指定代数的方法进行停止程序的运行,但是精确度较低,亦可以根据个体的差异来判断,通过计算种群中基因多样性测度,即所有基因位相似程度来进行控制
来一个实际的例子加代码(本人也正在学习java,如有不足之处欢迎指出)
用遗传算法( GA )求如下问题的最优解, x1, x2精确到小数点后2位。 (采用二进制编码方法)
max f (x1, x2) = 2x1·sin(8p x2) +x2·cos(13p x1)
x1:[-3,7]
x2:[-4,10]
代码如下:
结果:
模拟自然界优胜劣汰的进化现象,把搜索问题转化为遗传问题,把可能的解转为成一个向量——染色体,向量的每个元素称为基因。通过不断计算各染色体的适应值,选择最好的染色体,获得最优解。
基本概念 (以下均以二进制串 a=<1000101110110101000111> 为例)
1. 遗传:子代和父代具有相同或相似的性状,保证物种的稳定性;
2. 变异:子代与父代,子代不同个体之间总有差异,是生命多样性的根源;
3. 生存斗争和适者生存:具有适应性变异的个体被保留,不具适应性变异的个体被淘汰。
自然选择过程是长期的、缓慢的、连续的过程。
4. 个体与种群
● 个体就是模拟生物个体而对问题中的对象(一般就是问题的解)的一种称呼,一个个体也就是搜索空间中的一个点。
● 种群就是模拟生物种群而由若干个体组成的群体, 它一般是整个搜索空间的一个很小的子集。
5. 适应度与适应度函数
● 适应度就是借鉴生物个体对环境的适应程度,而对问题中的个体对象所设计的表征其优劣的一种测度。
● 适应度函数就是问题中的全体个体与其适应度之间的一个对应关系。它一般是一个实值函数。该函数就是遗传算法中指导搜索的评价函数,数值越接近目标值则说明适应度越高。
6. 染色体与基因
● 染色体(chromosome)就是问题中个体的某种字符串形式的编码表示。字符串中的字符也就称为基因。
7. 遗传操作
亦称遗传算子(genetic operator),就是关于染色体的运算。遗传算法中有三种遗传操作:
● 选择 (selection)
● 交叉(crossover,亦称交换、交配或杂交)
● 变异(mutation,亦称突变)
现在写个简单的例子:设 f(x) = -x2 + 2x + 0.5,求 max f(x), x在[-1, 2]之间。
对于二进制串 a=<1000101110110101000111> ;
1.先将其转为十进制数:ve=2288967
2.将其转化为[-1,2]内的实数为:
X=-1+ve*(2-(-1))/((2^22)-1)=0.631797
3.随机的产生一个初始群体(这里假设初始群体的个体数为 4)
pop1={
<1101011101001100011110>, % a1
<1000011001010001000010>, % a2
<0001100111010110000000>, % a3
<0110101001101110010101>} % a4
4.转化成 [-1, 2] 之间的十进制数即为
pop1={ 1.523032,0.574022,-0.697235,0.247238}
5.定义适应函数和求适应值
由于目标函数 f(x) 在 [-1, 2] 内的值有正有负,所以必须通过建立适应函数与目标函数的映射关系,保证映射后的适应值非负,而且目标函数的优化方向应对应于适应值增大的方向,也为以后计算各个体的入选概率打下基础。
最后假设得到适应值:
g(pop1)={2.226437,2.318543, 0,1.933350}
6.算出入选下一代的概率:
p(pop1)=g(pop1)/sum(g(pop1))
={0.343675, 0.357892, 0, 0.298433}
7.产生种群
newpop1={
<110101110 1001100011110>, % a1
<100001100 1010001000010>, % a2
<10000110010100 01000010>, % a2
<01101010011011 10010101>} % a4
8.交叉:
将第七步的加粗部分交换,(a1与a2,a3与a4)得到如下结果:
<1101011101010001000010>, % a1
<1000011001001100011110>, % a2
<10000110 0 1010010010101>, % a2
<0110101001101101000010>} % a4
9.变异:将a3中加粗基因变异:
<1101011101010001000010>, % a1
<1000011001001100011110>, % a2
<10000110 1 1010010010101>, % a2
<0110101001101101000010>} % a4
10.终止:我们可以采用遗传指定代数的方法进行停止程序的运行,但是精确度较低,亦可以根据个体的差异来判断,通过计算种群中基因多样性测度,即所有基因位相似程度来进行控制
来一个实际的例子加代码(本人也正在学习java,如有不足之处欢迎指出)
用遗传算法( GA )求如下问题的最优解, x1, x2精确到小数点后2位。 (采用二进制编码方法)
max f (x1, x2) = 2x1·sin(8p x2) +x2·cos(13p x1)
x1:[-3,7]
x2:[-4,10]
代码如下:
class chromasome{//染色体 public static final int DNAsize1=10; public static final int DNAsize2=11; int []DNA1=new int[DNAsize1]; int []DNA2=new int[DNAsize2]; chromasome(){ int a,b; for(int i=0;i<DNAsize1;i++){ a=(int)(0+Math.random()*(1-0+1)); DNA1[i]=a; } for(int i=0;i<DNAsize2;i++){ b=(int)(0+Math.random()*(1-0+1)); DNA2[i]=b; } } double twoToten1(){ String a ; a=moeth.velueTostr(this.DNA1); int d = Integer.parseInt(a, 2); // 2进制 double b=Math.pow(2, this.DNAsize1); return -3+(d*(7+3)/(b-1)); } double twoToten2(){ String a ; a=moeth.velueTostr(this.DNA2); int d = Integer.parseInt(a, 2); // 2进制 double b=Math.pow(2, this.DNAsize2); return -4+(d*(10+4)/(b-1)); } void variation(){//变异函数 } void getChromasome(){//输出看看染色体 System.out.println("-------------------"); for(int i=0;i<this.DNAsize1;i++){ System.out.print(this.DNA1[i]); } System.out.println(); for(int i=0;i<this.DNAsize2;i++){ System.out.print(this.DNA2[i]); } System.out.println(); System.out.println(this.adapt()-20); } double adapt(){//求适应值 //2x1·sin(8p x2) +x2·cos(13p x1) double x1=this.twoToten1(); //System.out.println("x1="+x1); double x2=this.twoToten2(); //System.out.println("x2="+x2); double value=2*x1*Math.sin(8*Math.PI*x2)+x2*Math.cos(13*Math.PI*x1); //System.out.println("value="+value); return value+20; } } public class genetic { /** * @param args */ int TEXT=1;//调试用的 static final int DNAnum=220; chromasome[] DNAarr=new chromasome[DNAnum]; double []adapt_arr=new double[DNAnum]; double []select_rate=new double [DNAnum]; static final double copulationRate=0.5;//交配概率 static final double variationRate=0.01;//变异概率 static int generationNum=0;//遗传代数 genetic(){ this.initDNA(); if(TEXT==1){ } } //-------------------------------------------------------------------------- void TEXToutput(){ for(int i=0;i<DNAnum;i++){ DNAarr[i].getChromasome(); } System.out.println(); } //-------------------------------------------------------------------------- void initDNA(){//随机生成多条染色体 for(int i=0;i<DNAnum;i++){ DNAarr[i]=new chromasome(); } } void formDNA(){ int a=this.DNAnum/6; DNAarr[DNAnum-1]=DNAarr[0]; //DNAarr[DNAnum-3]=DNAarr[0]; //DNAarr[DNAnum-5]=DNAarr[0]; //DNAarr[DNAnum-7]=DNAarr[0]; //DNAarr[DNAnum-2]=DNAarr[1]; //DNAarr[DNAnum-4]=DNAarr[1]; // for(int i=0;i<a;i++){ // DNAarr[DNAnum-i-1]=DNAarr[i]; // } //DNAarr[DNAnum-2]=DNAarr[0]; //DNAarr[DNAnum-3]=DNAarr[0]; //DNAarr[DNAnum-4]=DNAarr[1]; } // int chance(){//计算概率 // return 1; // } void select(){ double num=0; for(int i=0;i<this.DNAnum;i++){ //System.out.println("------------------------"+i+1+"---------------"); //DNAarr[i].getChromasome(); adapt_arr[i]=DNAarr[i].adapt(); num+=adapt_arr[i]; //System.out.println("-----------------------------------------------"); } for(int i=0;i<this.DNAnum;i++){ select_rate[i]=adapt_arr[i]/num; //System.out.println("------------------------"+i+1+"---------------"); //System.out.println("select_rate="+select_rate[i]); //System.out.println("----------------------------------------------"); } } void paixu(){ for(int i=1;i<select_rate.length;i++){ double m=select_rate[i]; chromasome n=DNAarr[i]; int k=i; for(int j=i-1;j>=0&&select_rate[j]<m;j--){ select_rate[j+1]=select_rate[j]; DNAarr[j+1]=DNAarr[j]; k--; } select_rate[k]=m; DNAarr[k]=n; } } void copulation(){//交配函数 int a; for(int j=1;j<DNAnum;j++){ a=(int)(1+Math.random()*(DNAarr[0].DNAsize1-1-1+1)); for(int i=a;i<DNAarr[j].DNAsize1;i++){ int b=DNAarr[j-1].DNA1[i]; this.DNAarr[j-1].DNA1[i]=DNAarr[j].DNA1[i]; this.DNAarr[j].DNA1[i]=b; } j++; } for(int j=1;j<DNAnum;j++){ a=(int)(1+Math.random()*(DNAarr[0].DNAsize2-1-1+1)); for(int i=a;i<DNAarr[j].DNAsize2;i++){ int l=DNAarr[j-1].DNA2[i]; this.DNAarr[j-1].DNA2[i]=DNAarr[j].DNA2[i]; this.DNAarr[j].DNA2[i]=l; } j++; } } void getDNA(){ for(int i=0;i<DNAnum;i++){ DNAarr[i].getChromasome(); } } void variation(){ //int m=(int)(1+Math.random()*(5-1+1)); //System.out.println(m); int m=3; while(m--!=0){ for(int a=0;a<DNAnum;a++){ int b=a; int a_1=(int)(0+Math.random()*(DNAarr[0].DNAsize1-1-0+1)); //int b=(int)(0+Math.random()*(DNAnum-1-0+1)); int b_1=(int)(0+Math.random()*(DNAarr[0].DNAsize2-1-0+1)); //System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$"+"a="+a+"b="+b+"a_1="+a_1+"b_1="+b_1); if(DNAarr[a].DNA1[a_1]==1){ DNAarr[a].DNA1[a_1]=0; }else{ DNAarr[a].DNA1[a_1]=1; } if(DNAarr[b].DNA2[b_1]==1){ DNAarr[b].DNA2[b_1]=0; }else{ DNAarr[b].DNA2[b_1]=1; } } } } public static void main(String[] args) { // TODO Auto-generated method stub int nn=20 ; while(nn--!=0){ int m=200; genetic g=new genetic(); g.select(); g.paixu(); int oo=0; while(m--!=0){ //System.out.println("##################################"); //g.getDNA(); //g.select(); g.copulation(); //System.out.println("--------------------交配-------------------"); //g.getDNA(); g.variation(); //System.out.println("-------------------变异------------------"); //g.getDNA(); g.select(); //System.out.println("--------------------选择-------------------"); //g.getDNA(); g.paixu(); //System.out.println("-------------------形成-------------------"); g.formDNA(); //g.select(); //g.getDNA(); } //g.getDNA(); //System.out.println(g.DNAarr[0].twoToten1()); //System.out.println(g.DNAarr[0].twoToten2()); System.out.println(g.DNAarr[0].adapt()-20); } } }
结果:
相关文章推荐
- HDU 4280Island Transport(Dinc非STL 模板)
- 使用Gson反序列化Json数据失败,报错JsonSyntaxException: java.lang.IllegalStateException
- linux 批量修改文件内容
- mac svn常用命令行
- hdu 3974 线段树 将树弄到区间上
- 多态的作用——通用性
- 复习一下两列布局。
- startActivityForResult 的使用
- 专题二1017
- 阶段冲刺4
- 非递归前序遍历二叉树
- C# 异常抛出-五分制
- FAILURE: Build failed with an exception.
- android AsyncTask介绍
- 活性基因免疫靶向细胞疗法
- 技术总结
- poj 1222 EXTENDED LIGHTS OUT 增广矩阵消元法
- 防止忘记
- C++的精髓——虚函数
- 二分图-最大匹配,最小路径覆盖,最小点覆盖