您的位置:首页 > 其它

遗传算法

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.定义适应函数和求适应值

由于目标函数 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);

}
}
}


结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: