IT老鸟,信息安全硕士。
分类: Java
2011-06-07 15:34:25
题目:y=x^5-6x^4+14x^3-2x^2+1 x属于1到20
手动计算一下:
x属于0到19
y=(x+1)^5-6(x+1)^4+14(x+1)^3-2(x+1)^2+1
=x^5-x^4+14x^2+19x+7
发现如果是16到19那么变异算法编码就很麻烦了。先不考虑这部分的问题
中文表述:
编码是L=4,依然采用2进制编码,自然数编码太复杂。我不懂。 所以群体规模我还
是取4,关于编码长度和群体规模的取值我查了一下文档,不知道这个怎么办。就按
照《遗传算法群体规模的研究》来看我还是取4.
然后随机取值。还是4个。既然是随机就用随机数生成函数来搞定。我用均匀分布,
然后在区间里面搞定。[0,3][4,7][8,11][12,15]然后四个区间,慢慢取。
下面进入自动的环节。前面全部都是人工干预的。
step1,计算适应度。即
yi=f(xi) 适应度 Y=yi/Εyi
step2,删除最低适应度的,将最高适应度的复制入最低适应度的。(这个就不算除法
了,反正y也是线性的,直接算极大值吧。)
step3,几个位交换x1和x4,x2和x3 0.5~0.8的概率 第一次玩0.65吧。
step4,变异,每个位,都可能变异吧。0.1的概率。
step5,还是长相完全一样就停止。
下面因为是未付费,而且是学术探讨所以具体代码不给出。超过100行和较难的编码一概不公开。
测试案例,后面给出了完备性算法的结果。结果发现最优解是x=3,y=109,而我算来算去都是x=4,y=108也算是差不多了,哪怕开始选择的时候也有x=3。遗传算法果然是非完备性算法。
Code: 1.
package 遗传算法; 2.
3.
public class test { 4.
5.
/** 6.
* @param args 7.
*/ 8.
public static void main(String[] args) { 9.
// TODO Auto-generated method stub 10. Genetic gen=new Genetic(); 11. Fuction fun=new Fuction(); 12. gen.Geneticmain();
13. System.out.println("下面是测试案例"); 14. for(int i=0;i<15;i++){ 15. System.out.println("x="+i+";y="+fun.fuctionValue(i)); 16. }
17.
18. }
19. 20. } Code: 1.
package 遗传算法; 2.
3.
public class Genetic { 4.
private static final double semaphore = 0.65; 5.
public int []cx={-1,-1,-1,-1}; 6.
public int []bix={-1,-1,-1,-1}; 7.
public int []cy={0,0,0,0}; 8.
public int ty=0;//total y 没啥用 9.
10.
11. Fuction fun=new Fuction();//调用 12.
13. //主函数 14. public void Geneticmain(){ 15. //初始化 16. init();
17. while(true){ 18. //计算适应度 19. for(int i=0;i 20. cy[i]=fun.fuctionValue(cx[i]);
21.
22. //选取最高值 23. maxToMin();
24.
25. //杂交 26. swap(bix[0],0,bix[3],3); 27. swap(bix[2],2,bix[1],1); 28.
29. //变异 30. variaty();
31. //判定函数 32. if(cx[0]==cx[1]&&cx[2]==cx[3]&&cx[3]==cx[1]) break; 33. }
34.
35. //打印结果 36. System.out.print("x="+cx[1]+";y="+cy[1]); 37. }
38. //变异函数 39. private void variaty() { 40. 。。 41. }
42. //变异 43. private void vary(int i, int j) {
44. 。。 45. }
46. //是否变异 47. private boolean isVary() { 48. boolean flag=false; 49. if(Math.random()<=0.1) flag=true; 50. return flag; 51. }
52. //杂交函数 53. private void swap(int x, int j, int y, int k) { 54. 。。 55. }
56. //位交换 57. private void swapbit(int x, int y, int i) { 58. 。。
59.
60. }
61.
62. }
63. //是否交换 64. private boolean isswap() { 65. 。。 66. }
67. //最大值复制到最小值里面 68. void maxToMin(){ 69. 。。 70. }
71. //单个适应度计算 72. int sufficient(int i){ 73. int flag=0; 74. flag=cy[i]/ty;
75. return flag; 76. }
77.
78. //初始化x 79. void init() 80. {。。 81. }
82. int TenToTwo(int x){ 83. int flag=0; 84. if(x>=8){ 85. flag+=1000;x-=8; 86. }else if(x>=4){ 87. flag+=100;x-=4; 88. }else if(x>=2){ 89. flag+=10;x-=2; 90.
91. }else if(x>=1) 92. flag+=1; 93.
94.
95. return flag; 96. }
97. int TwoToTen(int x){ 98. int flag=0; 99. if(x>=1000){ 100. flag+=8;x-=1000; 101. }else if(x>=100){ 102. flag+=4;x-=100; 103. }else if(x>=2){ 104. flag+=2;x-=10; 105.
106. }else if(x>=1) 107. flag+=1; 108.
109. return flag; 110.
111. }
112.
113. } 上面公开的有遗传算法的主函数,伪二进制转化成十进制,伪十进制转化成二进制。 下面是关于函数部分。这个有可能是要手动调整的。 Code: 1.
package 遗传算法; 2.
3.
public class Fuction { 4.
public int[] x={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; 5.
//{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; 6.
public int fuctionValue(int x){ 7.
int flag=0; 8.
int y=0; 9.
y=x^5-x^4+14*x^2+19*x+7; 10. flag=y;
11. return flag; 12. }
13. 14. } 一共代码250行。写了大概7小时。如果有探讨欢迎探讨。伸手党我也准备了伪的2~10进制相互转化。