用一个简单的实例带大家走进遗传算法的神奇世界。
问题描述:
求下面二元函数的最大值:
遗传算法主要核心包括:编码,初始种群的产生,适应度计算,选择算子,交叉算子,变异算子。
这个示例中采用二进制编码,x1,x2的范围在[1-7]直接,可以选择3位二进制进行编码,3为二进制编码刚好和每个数字对应。适应度计算,可以采取目标函数f(x1.x2),算法具体实现如下:
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Random;
- /**
- * Created by yaobo on 2016/6/20.
- */
- public class GAMAX {
- public static int MaxGen=1000;//最大遗传代数
- public static int generate;//全局变量,控制循环的代数
- double Pc=0.7;//交叉概率
- double Pm=0.05;//变异概率
- int Chromlenth=6;//染色体长度
- int scale=10;// 种群规模
- int everchromlength=3;//变量的编码长度
- int bestIndex;//当前代最好个体的索引
- int worstIndex;//当前代最坏个体的索引
- Individual bestIndividual;//当前代最好的个体
- Individual worstIndividual;//当前代最坏的个体
- Individual currentBest=new Individual();
- static double Rs=00.;//保存出现最好结果值
- static int Rsindex=-1;//保存出现最好结果的代数
- Individual[] population=new Individual[scale];//定义数组保存种群
- Random random=new Random();//随机函数
- public static void main(String[] args) {
- GAMAX gamax=new GAMAX();
- generate=0;//从0代开始
- gamax.generateInitalPopulation();//产生第一代个体
- gamax.evaluatePopulation();
- while (generate<MaxGen){//循环迭代
- generate++;
- gamax.generateNextPopulation();
- gamax.evaluatePopulation();
- gamax.performEvolution();
- gamax.printInf();
- gamax.findBest();
- }
- System.out.println("最优结果"+Rs+"产生代数"+Rsindex);
- }
- void findBest(){//找到最好的结果和代数
- if(Rs<bestIndividual.fitness){
- Rs=bestIndividual.fitness;
- Rsindex=bestIndex;
- }
- }
- void generateNextPopulation(){//产生下一代样本
- selectionOperator();
- crossoverOperator();
- mutationOperator();
- }
- void evaluatePopulation(){
- calculateFitnessValue();
- findBestAndWorstIndividual();
- }
- void generateInitalPopulation(){//产生第一代样本种群
- StringBuffer sb;
- Individual individual;
- for(int i=0;i<scale;i++){
- sb=new StringBuffer();
- for(int j=0;j<Chromlenth;j++){
- sb.append(((random.nextInt(65535)%10)<5)?'0':'1');
- }
- individual=new Individual();
- individual.chrom=sb.toString();
- population[i]=individual;
- }
- }
- void mutationOperator(){//变异算子
- double p;
- for (int i=0;i<scale;i++){
- for(int j=0;j<Chromlenth;j++) {
- p = random.nextInt(65535) % 1000 / 1000.0;
- if (p < Pm) {
- char temp=population[i].chrom.charAt(j);
- temp=(temp=='1'?'0':'1');
- population[i].chrom=population[i].chrom.substring(0,j)+temp+population[i].chrom.substring(j+1);
- }
- }
- }
- }
- void crossoverOperator(){//交叉算子
- ArrayList<Integer> index=new ArrayList<Integer>();
- int point;
- double p;
- String str1,str2;
- for(int i=0;i<scale;i++){
- index.add(i);
- }
- Collections.shuffle(index);//随机打乱样本,也就是随机配对
- for(int i=0;i<scale-1;i=i+2){
- p=random.nextInt(65535)%1000/1000.0;
- if(p<Pc){//如果小于这个数,则进行交叉遗传
- point=random.nextInt(65536)%(Chromlenth-1)+1;
- str1=population[index.get(i)].chrom.substring(point);
- str2=population[index.get(i+1)].chrom.substring(point);
- population[index.get(i)].chrom= population[index.get(i)].chrom.substring(0,point)+str2;
- population[index.get(i+1)].chrom= population[index.get(i+1)].chrom.substring(0,point)+str1;
- }
- }
- }
- void selectionOperator(){//选择算子并计算累积概率
- double p;
- double sum=0;
- double[] cfitness=new double[scale];
- int index;
- Individual[] newpoputation=new Individual[scale];//新的种群
- for (int i=0;i<scale;i++){
- sum+=population[i].fitness;
- }
- for(int i=0;i<scale;i++){
- cfitness[i]=population[i].fitness/sum;
- }
- for(int i=1;i<scale;i++){
- cfitness[i]=cfitness[i]+cfitness[i-1];
- }
- for(int i=0;i<scale;i++){
- p=random.nextInt(65535)%1000/1000.0;
- index=0;
- while (p>cfitness[index]){
- index++;
- }
- newpoputation[i]=population[index];
- }
- for(int i=0;i<scale;i++){
- population[i]=newpoputation[i];
- }
- }
- void findBestAndWorstIndividual(){//找出当前最好的个体
- bestIndividual=population[0];
- worstIndividual=population[0];
- for(int i=0;i<scale;i++){
- if(population[i].fitness>bestIndividual.fitness){
- bestIndividual=population[i];
- bestIndex=i;
- }
- else if(population[i].fitness<worstIndividual.fitness){
- worstIndividual=population[i];
- worstIndex=i;
- }
- }
- if(generate==0){
- currentBest=bestIndividual;
- }
- else {
- if(bestIndividual.fitness>currentBest.fitness){
- currentBest=bestIndividual;
- }
- }
- }
- void calculateFitnessValue(){//计算个体的适应度值
- String temp1,temp2;
- double x1,x2;
- for(int i=0;i<scale;i++){
- temp1=Integer.valueOf(population[i].chrom.substring(0,everchromlength),2).toString();
- temp2=Integer.valueOf(population[i].chrom.substring(everchromlength),2).toString();
- x1=Integer.parseInt(temp1)*Integer.parseInt(temp1);
- x2=Integer.parseInt(temp2)*Integer.parseInt(temp2);
- population[i].fitness=x1+x2;
- }
- }
- public void performEvolution(){
- if(bestIndividual.fitness>currentBest.fitness){
- currentBest=population[bestIndex];
- }else {
- population[worstIndex]=currentBest;
- }
- }
- void printInf(){
- double sum=0;
- double average;
- for (int i=0;i<scale;i++){
- sum+=population[i].fitness;
- }
- average=sum/scale;
- System.out.println("generate " + generate + " ava " + average + " best " + currentBest.fitness + " chrom " + currentBest.chrom);
- }
- }
- class Individual{
- String chrom;
- double fitness;
- }