[项目部]项目A组Leader(邱震钰):轻量级遗传算法库VGL:SGA


之前一直考虑写一个略微通用的遗传算法库,发现自己的这个库对三角函数很敏感(较为容易的得到复合三角函数的精确解).

这里先介绍下遗传算法:

1:大部分问题都能转化为非线性规划解的形式(包括很多NP问题);

2:也就是类似Max Y = F(X1,X2,X3,...,Xn) + 限定方程组;

3:可以考虑多元牛顿迭代,不过收敛效果会由于F构造的不同而不同,而遗传算法的本质是模拟并行计算,所以效率有时会意想不到的好;

4:把X1...Xn 看成是基因序列个体,复制M份(M为偶数,方便以后配对)个体,进行如下操作:

           ①、评估个体适应度(也就是方程的适合程度,用目标函数评估)

           ②、和自然选择类似,适应度高的个体存活几率更大,按概率分布来分配M个不同个体的重新数量分布

           ③、进行个体染色体配对互换(让所有个体自由随机配对,并随机在基因序列上切割等位段互换)

           ④、进行基因突变(每个个体的每个基因都有基因突变的概率)

           ⑤、若指定的进化代数没有到达,回到①

5:得到进化了K代的最优基因个体,并转化为表现型(目标解)

6:以后可以考虑引入二分以及其它类型的决策搜索到SGA,让它更具有演化效率。

 

贴一个Demo,解决:

max f(x,y,z,k,v) = 200sin(y/50.0)cos(y/50.0)+((-x^2+2x)-(z-a3)^2-20(k-a4)^2+5500.0)/(5000.0-(v-a5)^2);

 

限定条件比较简单,就是五个自变量的范围,这里取的不大(多元变量定义域越大,所需要的基因长度越长)

 

  1 /* VGL:demo_sga.cpp */
2
3 #include "SGA_VGL.h"
4 #include <conio.h>
5
6 using namespace vgl;
7
8 double AssessFunc(char * gene, int gNum)//多元目标函数返回值需要转换成Value>=0
9 {
10 static const int a1=1, a2=0, a3=3, a4=1, a5=1;//可变常量
11 static const int segList[]={0, 6, 12, 18, 24, 30};//基因序列表现型关键节点
12 double lfList[5];//用于存储对应的5个基因表现型
13 //求 max=200sin(y/50.0)^2+((-x^2+2x)-(z-a3)^2-20(k-a4)^2+5500.0)/(5000.0-(v-a5)^2);
14 //可以是任意多元函数+限定方程组
15 //限定方程组任意条件一旦不满足,可以让返回值为相对最小值,达到过滤作用
16 //任意n元 f(x1,x2,x3,x4,...,xn)=Y 恒等式都可以转化为最大值的形式来求解
17 if(gene==0)
18 return 0.0;
19 SGA::fromGeneToDouble(gene,segList,5,lfList);
20 double x=lfList[0];//x是二进制gene的表现型
21 double y=lfList[1];
22 double z=lfList[2];
23 double k=lfList[3];
24 double v=lfList[4];
25
26 return 200*sin(y/50.0)*cos(y/50.0)+((-x*x+2*x)-(z-a3)*(z-a3)-20*(k-a4)*(k-a4)+5500.0)/(5000.0-(v-a5)*(v-a5));
27 }
28 void DisplayGroup(SGA & group,int generation,double pro)//output group's gene
29 {
30 static int no=1;
31 char * tStr=new char[group.getGenNum()+1];
32 memset(tStr,0,group.getGenNum()+1);
33
34 cout << endl;
35 cout << "Evolution No." << no++ << ":(generation=" <<generation/1000.0<<"kG,variationPro="<<pro*100.0 <<"% )"<<endl;
36 cout << "Best result:\n>>";
37 cout << group.getBest() << endl;
38 cout << "BestGen:\n>>";
39 memcpy(tStr,group.getBestGene(),group.getGenNum());
40 for(int j=0; j < group.getGenNum(); j++)
41 tStr[j]+='0';
42
43 cout << tStr << endl;
44
45 delete [] tStr;
46
47 }
48 int main(int argc, char * argv[])
49 {
50
51 SGA sga;
52
53 sga.encodeGene(30,30,0.35f);//每个个体30个基因,30个个体,单个个体突变某一个基因的概率为0.35
54 sga.freshAssess(AssessFunc);//传入回调函数:评估函数
55 sga.run(1500);//开始迭代演化1500代
56 DisplayGroup(sga,1500,0.35f);//显示当前种群情况
57
58 sga.freshInit(sga.getBestGene());//把第一次最优个体基因复制30份
59 sga.freshPro(0.5f);//把基因突变概率提高为0.5
60 sga.run(10000);
61 DisplayGroup(sga,10000,0.5f);//显示当前种群情况
62
63 sga.freshInit(sga.getBestGene());//把第二次最优个体基因复制30份
64 sga.freshPro(0.85f);//把基因突变概率提高为0.8,能够增加最优解搜索速度
65 sga.run();//开始按默认次数演化
66 DisplayGroup(sga,10000,0.85f);//显示当前种群情况
67
68 sga.freshInit(sga.getBestGene());//把第三次最优个体基因复制30份
69 sga.freshPro(0.35f);//把基因突变概率下降为0.1
70 sga.run(10000);
71 DisplayGroup(sga,10000,0.35f);//显示当前种群情况
72
73 sga.freshInit(sga.getBestGene());//把第三次最优个体基因复制30份
74 sga.freshPro(0.15f);//把基因突变概率下降为0.1
75 sga.run(10000);
76 DisplayGroup(sga,10000,0.15f);//显示当前种群情况
77
78
79 const int a1=1, a2=0, a3=3, a4=1, a5=1;//可变常量
80 const int segList[]={0, 6, 12, 18, 24, 30};//基因序列表现型关键节点
81 double lfList[5];//用于存储对应的5个基因表现型
82
83 SGA::fromGeneToDouble(sga.getBestGene(),segList,5,lfList);
84 double x=lfList[0];//x是二进制gene的表现型
85 double y=lfList[1];
86 double z=lfList[2];
87 double k=lfList[3];
88 double v=lfList[4];
89 double Y=200*sin(39/50.0)*cos(39/50.0)+((-1*1+2*1)-(a3-a3)*(a3-a3)-20*(a4-a4)*(a4-a4)+5500.0)
90 /(5000.0-(63-a5)*(63-a5));
91 cout<<endl<<endl<<">>(x,y,z,k,v)"<<endl;
92 cout<<">>dx="<<x - a1<<endl
93 <<">>dy="<<y - 39<<endl
94 <<">>dz="<<z - a3<<endl
95 <<">>dk="<<k - a4<<endl
96 <<">>dv="<<v - 63<<endl
97 <<">>dY="<<- ( sga.getBest() - Y )<<endl
98 <<endl<<"Evolution Over"<<endl;
99 sga.decodeGene();//结束当前种群迭代任务
100 _getch();
101 return 0;
102 }




输出结果(每次结果都有所不同,但都会一定程度上趋近最优):

Evolution No.1:(generation=1.5kG,variationPro=35% )
Best result:
>>101.096
BestGen:
>>000010100111001000000100001111


Evolution No.2:(generation=10kG,variationPro=50% )
Best result:
>>101.886
BestGen:
>>000010100111001000000000101111


Evolution No.3:(generation=10kG,variationPro=85% )
Best result:
>>104.713
BestGen:
>>000010100111001000000000111111


Evolution No.4:(generation=10kG,variationPro=10% )
Best result:
>>104.727
BestGen:
>>000010100111000000000000111111


Evolution No.5:(generation=10kG,variationPro=10% )
Best result:
>>104.744
BestGen:
>>000010100111000000000001111111



>>(x,y,z,k,v)
>>dx=1
>>dy=0
>>dz=-3
>>dk=0
>>dv=0
>>dY=0.00865052

Evolution Over


以上是演化了上万次的结果,dY是其中的误差值,在这个例子里效果还是不错的。


 

点这里下载源代码

 

有兴趣或有任何建议的请提出,想BS的各位尽情BS.......

 

posted on 2011-11-08 23:32  信息科学-腾讯校园之星协会联盟(ISA-TCS)  阅读(2053)  评论(0编辑  收藏  举报