java实现遗传算法(GA)解决基本数学问题(入门级)

1.简述

关于遗传算法-百度百科的介绍,直接百度百科吧

2.数学问题

在这里插入图片描述
这个比较简单的数学公式
当a,b,c,d四个变量取值为 [-2,2] 时,Y的最小值是多少?a、b、c、d、分别是多少?
对与这种公式,凭借小学三年级的功底,得出:最小值 Y=-20,{a=2,b=-2,c=3,d=-2}
既然已经知道了最优解,接下来让我们写一下程序看看求出来到最优解是否与我们算出来的一致

3.java实现

package de;

public class MYDE {
	public static void main(String[] args) {
		int NP=10;//种群规模
		int SIZE=4; //需要有a、b、c、d,4个参数,所以是4
		int maxGen=200;//迭代次数
		double CR=0.2;//交叉概率
		double MU=0.2;//变异概率
		double MAX=-2;//abcd变量的上限
		double MIN=2;//abcd变量的下限
		double [][] init_population=new double [NP][SIZE];//初始化种群
		double [][] select_population=new double [NP][SIZE];//选择后的优质种群
		double [][] cr_population=new double [NP][SIZE];//交叉后种群
		double [][] mu_population=new double [NP][SIZE];//变异后种群
		double [] best_individual=new double [SIZE];	//精英个体,及全局最优解
		double  best_Y=Integer.MAX_VALUE;	//精英适应度
		
		double [] Y=new double[NP]; //对应种群中每个个体的适应度
		double [] addSumP=new double [NP];//每个个体被选中的概率累加和
		
		//1.初始化种群
		for(int i=0;i<NP;i++) {
			for(int j=0;j<SIZE;j++) {
				init_population[i][j]=MIN+Math.random()*(MAX-MIN);//随机生成解
			}
		}
		/*
		 * 种群初始化以后,就有了NP个解
		 */
		//迭代
		for(int G=0;G<maxGen;G++) {
			//2.选择优质个体,根据轮盘赌的形式挑选个体
			double sumY=0;
			for(int i=0;i<NP;i++) {//计算每个个体的适应度及全部适应度和
				Y[i]=function(init_population[i]); 
				sumY+=Y[i];
			}
			double addSum=0;
			for(int i=0;i<NP;i++) {//记录每个个体别选中的累加和
				addSum+=Y[i]/sumY;	//当前个体概率
				addSumP[i]=addSum;	//累加和
			//	System.out.println("累加和"+addSum);
			}
			//根据累加和概率,判断轮盘指针是向那个个体
			for(int i=0;i<NP;i++) {
				double r=Math.random();
				int index=0;
				for(int k=0;k<NP;k++) {
					if(r<addSumP[k]) {
						index=k;break;//选择了一个个体下标是index
					}
				}
				select_population[i]=init_population[index];
			}

			//3.交叉
			for(int i=0;i<NP;i++){
				double cr=Math.random();
				if(cr<CR) {//判断是否交叉
					//与哪个个体交叉,随机生成一个个体
					int indiv=(int)Math.random()*NP;
					//从那个位置交叉,随机生成一个位置
					int index=(int)Math.random()*SIZE;
					for(int j=0;j<SIZE;j++) {
						if(j>=index){//发生交叉的片段
							cr_population[i][j]=select_population[indiv][j];
						}else {		//不发生交叉的片段
							cr_population[i][j]=select_population[i][j];
						}
					}
				 }else {
					for(int j=0;j<SIZE;j++) {	
							cr_population[i][j]=select_population[i][j];	
					}
				}
			}
	
			//4.变异
			for(int i=0;i<NP;i++){
				for(int j=0;j<SIZE;j++) {
					double mu=Math.random();
					if(mu<MU) {			//判断是否变异
						mu_population[i][j]=MIN+Math.random()*(MAX-MIN);	
					}else {
						mu_population[i][j]=cr_population[i][j];	
					}
				}
			}
			//输出当前迭代中最优解
			for(int i=0;i<NP;i++){
				if(best_Y>function(mu_population[i])) {
					for(int j=0;j<SIZE;j++){
					best_individual[j]=	mu_population[i][j];
					}
					best_Y=function(mu_population[i]);
				}
				
			}
			System.out.println("第"+G+"代,最小适应度为:"+best_Y);
			
			//5.保留优质个体
			for(int i=0;i<NP;i++){
				if(function(init_population[i])>function(mu_population[i])) {
					for(int j=0;j<SIZE;j++) {	
						init_population[i][j]=mu_population[i][j];						
					}	
				}
			}
		}//迭代结束
		System.out.println("最优解空间为:");
		for(int j=0;j<SIZE;j++){
			System.out.print(" "+best_individual[j]);
		}
	}
	//计算适应度,及函数式的解
	public static double function(double [] individual) {
		//传入个体计算Y值
		double result=-individual[0]+2*individual[1]-3*individual[2]+4*individual[3];
		return result;
	}

}
//微信搜索公众号:六行代码
//可以同作者讨论答疑

4.结果展示

0,最小适应度为:-0.297311691540516071,最小适应度为:-7.9206327027528412,最小适应度为:-11.9397885171772273,最小适应度为:-11.9397885171772274,最小适应度为:-11.9397885171772275,最小适应度为:-12.8129222594689766,最小适应度为:-12.8129222594689767,最小适应度为:-12.9759299098682618,最小适应度为:-13.7094093644460679,最小适应度为:-13.70940936444606710,最小适应度为:-14.070832230733176
...195,最小适应度为:-19.726396004677348196,最小适应度为:-19.726396004677348197,最小适应度为:-19.726396004677348198,最小适应度为:-19.726396004677348199,最小适应度为:-19.726396004677348
最优解空间为:
 1.9578436000419988 -1.9990331025187396 1.9319300848728265 -1.9936739862448478

5.总结
根据对照得出,算法最后是朝着最优的方向进行的,得出来的最优解并不是真的最小值,只是一直无限的接近最小值。
GA算法还有其他的改进方法,比如交叉的方式、变异的数量、个体的取舍、并行遗传等等

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海绵泡泡~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值