Java算法---遗传算法示例

              用一个简单的实例带大家走进遗传算法的神奇世界。

  问题描述:

        求下面二元函数的最大值:

        《Java算法---遗传算法示例》《Java算法---遗传算法示例》

       遗传算法主要核心包括:编码,初始种群的产生,适应度计算,选择算子,交叉算子,变异算子。

      这个示例中采用二进制编码,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;
}

    原文作者:遗传算法
    原文地址: https://blog.csdn.net/csdn_yaobo/article/details/51727320
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞