利用标准遗传算法求解函数

package wh.algorithm;

public class SGA {
	private static Bion best = null; // 最佳个体
	private static String[] ipop = new String[10];// 染色体
	private static int gernation = 0;// 染色体代号
	private static final int GENE = 22;// 基因数
	private static int INTERVALVALUE=255;
	private static final int EVOLUTION_NUMBER=100000;//进化次数

	public static void main(String[] args) {
		System.out.printf("利用标准遗传算法求解函数f(x)=(x-22)*(x-22)的最小值,X的区间[-%d,%d].\n",INTERVALVALUE,INTERVALVALUE);
		SGA sga = new SGA();
		String bestReuslt = sga.process();
		System.out.println(bestReuslt);
	}

	public SGA() {
		ipop = initPops();
	}

	/**
	 * 初始化一条染色体(用二进制字符串表示)
	 * 
	 * @return 一条染色体
	 */
	private String initPop() {
		String res = "";
		for (int i = 0; i < GENE; i++) {
			if (Math.random() > 0.5) {
				res += "0";
			} else {
				res += "1";
			}
		}
		return res;
	}

	/**
	 * 初始化一组染色体
	 * 
	 * @return 染色体组
	 */
	private String[] initPops() {
		String[] ipop = new String[10];
		System.out.println("初始化个体...");
		for (int i = 0; i < 10; i++) {
			ipop[i] = initPop();
			// System.out.printf("ipop[%d]:%s  %s\n", i, ipop[i],
			// Integer.parseInt(ipop[i], 2));
		}
		return ipop;
	}

	/**
	 * 将染色体转换成x的值
	 * 
	 * @param str
	 *            染色体
	 * @return 染色体的适应值
	 */
	private double calculatefitnessvalue(String str) {
		double x = binary2Double(str);		
		double fitness = -(x - 22) * (x - 22);
		// System.out.printf("X=%f,f(x)=%f\n",x,fitness);
		return fitness;
	}

	/**
	 * 计算群体上每个个体的适应度值; 按由个体适应度值所决定的某个规则选择将进入下一代的个体;
	 */
	private void select() {
		double evals[] = new double[10]; // 所有染色体适应值
		double p[] = new double[10]; // 各染色体选择概率
		double q[] = new double[10]; // 累计概率
		double F = 0; // 累计适应值总和
		for (int i = 0; i < 10; i++) {
			evals[i] = calculatefitnessvalue(ipop[i]);
			if (best == null) {
				best = new Bion();
				best.fitness = evals[i];
				best.generations = 0;
				best.chromosome = ipop[i];
			} else {
				if (evals[i] > best.fitness) // 最好的记录下来
				{
					best.fitness = evals[i];
					best.generations = gernation;
					best.chromosome = ipop[i];
				}
			}
			F = F + evals[i]; // 所有染色体适应值总和

		}
		for (int i = 0; i < 10; i++) {
			p[i] = evals[i] / F;
			if (i == 0)
				q[i] = p[i];
			else {
				q[i] = q[i - 1] + p[i];
			}
		}
		for (int i = 0; i < 10; i++) {

			double r = Math.random();
			if (r <= q[0]) {
				ipop[i] = ipop[0];

			} else {
				for (int j = 1; j < 10; j++) {
					if (r < q[j]) {
						ipop[i] = ipop[j];
						break;
					}
				}
			}
		}
	}

	/**
	 * 交叉操作 交叉率为25%,平均为25%的染色体进行交叉
	 */
	private void cross() {
		String temp1, temp2;
		for (int i = 0; i < 10; i++) {
			if (Math.random() < 0.25) {
				double r = Math.random();
				int pos = (int) (Math.round(r * 1000)) % GENE;
				if (pos == 0) {
					pos = 1;
				}
				temp1 = ipop[i].substring(0, pos)
						+ ipop[(i + 1) % 10].substring(pos);
				temp2 = ipop[(i + 1) % 10].substring(0, pos)
						+ ipop[i].substring(pos);
				ipop[i] = temp1;
				ipop[(i + 1) / 10] = temp2;
			}
		}
	}

	/**
	 * 基因突变操作 1%基因变异m*pop_size 共180个基因,为了使每个基因都有相同机会发生变异, 需要产生[1--180]上均匀分布的
	 */
	private void mutation() {
		for (int i = 0; i < 4; i++) {
			int num = (int) (Math.random() * GENE * 10 + 1);
			int chromosomeNum = (int) (num / GENE) + 1; // 染色体号

			int mutationNum = num - (chromosomeNum - 1) * GENE; // 基因号
			if (mutationNum == 0)
				mutationNum = 1;
			chromosomeNum = chromosomeNum - 1;
			if (chromosomeNum >= 10)
				chromosomeNum = 9;
			// System.out.println("变异前" + ipop[chromosomeNum]);
			String temp;
			if (ipop[chromosomeNum].charAt(mutationNum - 1) == '0') {
				if (mutationNum == 1) {
					temp = "1" + ipop[chromosomeNum].substring(mutationNum);
				} else {
					if (mutationNum != GENE) {
						temp = ipop[chromosomeNum].substring(0, mutationNum - 1)+ "1"+ ipop[chromosomeNum].substring(mutationNum);
					} else {
						temp = ipop[chromosomeNum].substring(0, mutationNum - 1) + "1";
					}
				}
			} else {
				if (mutationNum == 1) {
					temp = "0" + ipop[chromosomeNum].substring(mutationNum);
				} else {
					if (mutationNum != GENE) {
						temp = ipop[chromosomeNum].substring(0, mutationNum -
						1) + "0" + ipop[chromosomeNum].substring(mutationNum);
					} else {
						temp = ipop[chromosomeNum].substring(0, mutationNum - 1) + "1";
					}
				}
			}
			ipop[chromosomeNum] = temp;
			// System.out.println("变异后" + ipop[chromosomeNum]);
		}
	}

	public double binary2Double(String binary) {
		return -INTERVALVALUE + Integer.parseInt(binary, 2) * (INTERVALVALUE - (-INTERVALVALUE))
				/ (Math.pow(2, GENE) - 1);
	}

	/**
	 * 执行遗传算法
	 */
	public String process() {
		System.out.printf("开始进化,进化次数%d\n",EVOLUTION_NUMBER );
		System.out.printf("进化中............\n");
		long startTime = System.nanoTime();
		String str = "";
		for (int i = 0; i < EVOLUTION_NUMBER; i++) {
			this.select();
			this.cross();
			this.mutation();
			gernation = i;
		}
		long endTime = System.nanoTime();
		long costtime = endTime - startTime;
		System.out.printf("进化耗时:%d(ms)\n", costtime / 1000000);
		str = "最小值F(X)=" + best.fitness + " ,X="
				+ binary2Double(best.chromosome) + ",第" + best.generations
				+ "个染色体";

		return str;
	}

}

class Bion {
	public int generations; // 最佳适应值代号
	public String chromosome; // 最佳染色体
	public double fitness; // 最佳适应值
}


测试结果:

利用标准遗传算法求解函数f(x)=(x-22)*(x-22)的最小值,X的区间[-255,255].
初始化个体...
开始进化,进化次数100000
进化中............
进化耗时:4003(ms)
最小值F(X)=-4.382968527749637E-6 ,X=21.997906445957767,第66072个染色体

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值