• [原]遗传算法Java实现源代码


    【Title】[原]遗传算法Java实现源代码
    【Date】2013-04-07
    【Abstract】以前学习遗传算法时,用Java实现的遗传算法程序,现整理分享出来。
    【Keywords】wintys、遗传、算法、algorithm、种群、基因、个体、进化、染色体、适应度、Rosenbrock
    【Environment】Windows 7、PowerDesigner16
    【Author】wintys (wintys@gmail.com) http://wintys.cnblogs.com
    【URL】http://www.cnblogs.com/wintys/archive/2013/04/07/genetic_algorithms.html

    【Content】:

    1、简介

        此程序是对照《遗传算法原理及应用》(周明、孙树栋编著),附录所列C程序改编而来,用Java实现的遗传算法程序。相关理论请参考《遗传算法原理及应用》。

    2、类图

        类图由源代码经PowerDesigner反向生成。

     

       (类图)

    3、代码

    3.1、染色体

        //染色体:Chromesone.java
        class Chromosome implements Cloneable{
            private StringBuffer chromosome;
            private int chromosomeLength;//染色体长度
            private char defaultChar; //默认基因填充字符
            
            public Chromosome(int chromosomeLength){
                chromosome = new StringBuffer(chromosomeLength);
                chromosome.setLength(chromosomeLength);
                defaultChar = '0';
                this.chromosomeLength = chromosomeLength;
            }
            
            //设置基因
            public boolean setGene(int begin , int end , String gene){
                int len = gene.length();
                
                if(len > end - begin + 1)
                    return false;
                    
                //index => chromosome , idx => gene
                for (int index = begin , idx = 0; index <= end; index++ , idx++) {
                    if(idx < len)
                        chromosome.setCharAt(index , gene.charAt(idx));
                    else
                        chromosome.setCharAt(index , defaultChar);
                }
                
                return true;    
            }
            
            //获取基因
            public String getGene(int begin , int end){
                char[] dest = new char[end - begin + 1];
                chromosome.getChars(begin , end + 1 , dest , 0);

                return new String(dest);        
            }
            
            public int getLength(){
                return chromosomeLength;
            }
            
            public String toString(){
                return chromosome.toString();
            }
            
            @Override
            public     Object clone()throws CloneNotSupportedException{
                Chromosome c = null;
                try{
                    c = (Chromosome)super.clone();
                    c.chromosome = new StringBuffer(chromosome);
                }catch(CloneNotSupportedException e ){
                    System.out.println(e.getMessage());
                }

                return c;    
            }
        }

    3.2、个体

    3.2.1、抽象个体

        //Individual.java
        abstract class Individual implements Cloneable{
            protected Chromosome chrom;//个体基因型:一个基因型染色体由多个基因组成
            protected int genelen;//基因长度
            protected double fitness;//适应度
            protected double targetValue;//目标函数值
            
            public abstract void coding();//编码
            public abstract void decode();//解码
            public abstract void calFitness();//计算个体适应度
            public abstract void generateIndividual();//随机产生个体
            public abstract void calTargetValue();//获取目标函数值
            
            public double getFitness(){
                return fitness;
            }
            
            public double getTargetValue(){
                return targetValue;
            }
            
            public int getChromlen(){
                return chrom.getLength();
            }
            
            public boolean setChrom(int begin , int end , String gene){
                return chrom.setGene(begin,end,gene);
            }
            
            public String getChrom(int begin , int end){
                return chrom.getGene(begin,end);
            }
            
            public void mutateSingleBit(int index){
                String gene , gn;
                gene = chrom.getGene(index , index);
                gn = gene.equals("0") ? "1":"0";
                chrom.setGene(index , index , gn);
            }
            
            @Override
            public Object clone(){
                Individual indv = null;
                
                try{
                    indv = (Individual)super.clone();
                    indv.chrom = (Chromosome)chrom.clone();
                }catch(CloneNotSupportedException e ){
                    System.out.println(e.getMessage());
                }
                
                return indv;
            }
        }

    3.2.2、Rosenbrock个体实现

        //RosenbrockIndividual.java
        class RosenbrockIndividual extends Individual {
            private double x1 , x2; // 个体表现型
            //基因型chromosome由 (x1 , x2)编码而成
            
            RosenbrockIndividual(int chromlen){
                genelen = 10;
                chrom = new Chromosome(chromlen);
            }
            
            //编码
            public void coding(){
                String code1,code2;
                code1 = codingVariable(x1);
                code2 = codingVariable(x2);
                
                chrom.setGene(0 , 9 , code1);
                chrom.setGene(10, 19 , code2);
            }
            
            //解码
            public void decode(){
                String gene1,gene2;
                
                gene1 = chrom.getGene(0 , 9);
                gene2 = chrom.getGene(10 , 19);
                
                x1 = decodeGene(gene1);
                x2 = decodeGene(gene2);
            }
            
            //计算目标函数值
            public  void calTargetValue(){
                decode();
                targetValue = rosenbrock(x1 , x2);
            }
            
            //计算个体适应度
            public void calFitness(){
                fitness = getTargetValue();
            }
            
            private String codingVariable(double x){
                double y = (((x + 2.048) * 1023) / 4.096);
                String code = Integer.toBinaryString((int) y);
                
                StringBuffer codeBuf = new StringBuffer(code);
                for(int i = code.length(); i<genelen; i++)
                    codeBuf.insert(0,'0');
                    
                return codeBuf.toString();
            }
            
            private double decodeGene(String gene){
                int value ;
                double decode;
                value = Integer.parseInt(gene, 2);
                decode = value/1023.0*4.096 - 2.048;
                
                return decode;
            }
                
            public String toString(){
                String str = "";
                ///str = "基因型:" + chrom + "  ";
                ///str+= "表现型:" + "[x1,x2]=" + "[" + x1 + "," + x2 + "]" + "\t";
                str+="函数值:" + rosenbrock(x1 , x2) + "\n";
                
                return     str;    
            }
            
            /**
             *Rosenbrock函数:
             *f(x1,x2) = 100*(x1**2 - x2)**2 + (1 - x1)**2
             *在当x在[-2.048 , 2.048]内时,
             *函数有两个极大点:
             *f(2.048 , -2.048) = 3897.7342
             *f(-2.048,-2.048) = 3905.926227
             *其中后者为全局最大点。
             */
            public static double rosenbrock(double x1 , double x2){
                double fun;
                fun = 100*Math.pow((x1*x1 - x2) , 2) + Math.pow((1 - x1) , 2);
                
                return fun;
            }
            
            //随机产生个体
            public void generateIndividual(){
                x1 = Math.random() * 4.096 - 2.048;
                x2 = Math.random() * 4.096 - 2.048;
                
                //同步编码和适应度
                coding();
                calTargetValue();
                calFitness();
            }
        }

    3.3、种群

        //Population.java
        class Population{
            private int generation; //种群的代数
            private int size;            //群体大小
            private Individual[] pop;   //种群
            private double averageFitness;    //平均适应度
            private double[] relativeFitness;    //相对适应度
            private int chromlen;//基因长度
            Individual bestIndividual;//当前代适应度最好的个体
            Individual worstIndividual;//当前代适应度最差的个体
            Individual currentBest;//到目前代为止最好的个体
            private int worstIndex;//bestIndividual对应的数组下标

            
            public Population(int size){
                this.generation = 0;
                this.size = size;
                
                this.pop = new Individual[size];
                this.averageFitness = 0;
                this.relativeFitness = new double[size];
                this.chromlen = 20;
                
                for(int i = 0; i < size; i++){
                    pop[i] = new RosenbrockIndividual(chromlen);
                }
            }
            
            
            //初始化种群
            public void initPopulation(){
                for(int i = 0;i < size;i++){
                    pop[i].generateIndividual();
                }
                
                findBestAndWorstIndividual();                
            }

            //----------------------------------------------------
            //比例选择
            public void  select(){
                double[] rouletteWheel; //赌盘
                Individual[] childPop = new Individual[size];
                
                calRelativeFitness();
                
                //产生赌盘
                rouletteWheel  = new double[size];
                rouletteWheel[0] = relativeFitness[0];
                for(int i=1;i<size -1;i++){
                    rouletteWheel[i] = relativeFitness[i] + rouletteWheel[i - 1];
                }
                rouletteWheel[size - 1] = 1;
                
                //进行赌盘选择,产生新种群
                for(int i = 0;i < size ; i++){
                    double rnd = rand();
                    for(int j = 0; j < size; j++){
                        if(rnd < rouletteWheel[j]){
                            childPop[i] = pop[j];
                            break;
                        }    
                    }        
                }
                
                for(int i = 0;i < size; i++){
                    pop[i] = childPop[i];
                }
                
                //return     childPop;
            }
            
            //求总适应度
            private double calTotalFitness(){
                double total = 0;
                for(int i = 0 ; i < size ;i++)
                    total += pop[i].getFitness();
                return total;
            }
                
            //计算相对适应度
            public double[] calRelativeFitness(){
                double totalFitness = calTotalFitness();
                for(int i = 0 ;i < size ; i++){
                    relativeFitness[i] = pop[i].getFitness() / totalFitness;    
                }
                
                return relativeFitness;
            }
            
            //================================
            
            //------------------------------------------------------
            //单点交叉
            public void crossover(){
                for(int i = 0 ; i < size/2*2; i+=2){
                    int rnd;
                    //随机两两配对
                    rnd = rand(i , size);

                    if(rnd != i)
                        exchange(pop , i , rnd);
                        
                    rnd = rand(i , size);
                    if(rnd != i+1)
                        exchange(pop , i + 1 , rnd);    
                            
                    //交叉
                    double random = rand();

                    if(random < GeneticAlgorithms.crossoverRate){
                        cross(i);
                    }            
                }
            }
            
            //执行交叉操作
            private void cross(int i){
                String chromFragment1,chromFragment2;//基因片段
                
                int rnd = rand(0 , getChromlen() - 1);//交叉点为rnd之后,可能的位置有chromlen - 1个.
                chromFragment1 = pop[i].getChrom(rnd + 1 , getChromlen() - 1);
                chromFragment2 = pop[i+1].getChrom(rnd + 1 , getChromlen() - 1);
                    
                pop[i].setChrom(rnd + 1 , getChromlen() - 1 , chromFragment2);
                pop[i+1].setChrom(rnd + 1 , getChromlen() - 1 , chromFragment1);            
            }
            
            //产生随机数
            private int rand(int start , int end){//产生区间为[start , end)的随机整数
                return (int)(rand()*(end - start) + start);
            }
            
            //交换
            private void exchange(Individual[] p ,int src , int dest){
                Individual temp;
                temp = p[src];
                p[src] = p[dest];
                p[dest] = temp;    
            }
            //==============================

            //-----------------------------------------------------
            //变异
            public void mutate(){
                for(int i = 0 ; i < size;i++){
                    for(int j = 0 ;j < getChromlen(); j++){
                        if(rand() < GeneticAlgorithms.mutateRate){
                            pop[i].mutateSingleBit(j);
                            ///System.out.print("变异"+ i +" - "+ j + "  ");///
                        }    
                    }
                }
            }
            //==============================
            
            //-----------------------------------------------------
            //进化
            public void evolve(){
                select();
                crossover();
                mutate();
                evaluate();    
            }
            
            
            //==============================
            //计算目标函数值、适应度、找出最优个体。
            public void evaluate(){
                //同步目标函数值和适应度
                for(int i = 0; i < size; i++){
                    pop[i].calTargetValue();
                    pop[i].calFitness();
                }
                
                //使用最优保存策略(Elitist Model)保存最优个体
                findBestAndWorstIndividual();
                pop[worstIndex] = (Individual)currentBest.clone();
                
                generation++;    
            }    
            //找出适应度最大的个体
            public void findBestAndWorstIndividual(){
                bestIndividual = worstIndividual = pop[0];
                for(int i = 1; i <size;i++){
                    if(pop[i].fitness > bestIndividual.fitness){
                        bestIndividual = pop[i];
                    }
                    if(pop[i].fitness < worstIndividual.fitness){
                        worstIndividual = pop[i];
                        worstIndex = i;
                    }
                }
            
                if( generation == 0 ){//初始种群
                    currentBest = (Individual)bestIndividual.clone();
                }else{
                    if(bestIndividual.fitness > currentBest.fitness)
                        currentBest = (Individual)bestIndividual.clone();
                }
            }
            
            //判断进化是否完成
            public boolean isEvolutionDone(){
                if(generation < GeneticAlgorithms.maxGeneration)
                    return false;
                return true;    
            }
                
            //计算平均适应度
            public double calAverageFitness(){
                for(int i = 0 ; i < size; i++){
                    averageFitness += pop[i].getFitness();
                }
                averageFitness/=size;
                    
                return averageFitness;
            }
                        
            //产生随机数
            private double rand(){
                return Math.random();
            }
            
            public int getChromlen(){
                return chromlen;
            }
            
            public void setGeneration(int generation){
                this.generation = generation;
            }
            
            public int getGeneration(){
                return generation;
            }
            /*
            public String printPop(Individual[] pop){
                String str="";
                for(int i = 0 ; i < size ; i++)
                    str += pop[i];
                return str;
            }*/
            
            public String toString(){
                String str="";
                for(int i = 0 ; i < size ; i++)
                    str += pop[i];
                return str;
            }    
        }

    3.4 测试

        //GeneticAlgorithms.java 给定参数,测试遗传算法
        import java.io.*;
        //2008-11-21
        class GeneticAlgorithms{
            public static double crossoverRate;//交叉概率
            public static double mutateRate;//变异概率
            public static int maxGeneration;//进化代数
            public static int populationSize;//群体大小
            
            static {
                //crossoverRate = 0.6;
                //mutateRate = 0.001;
                //maxGeneration  = 100;
                //populationSize = 500;
                maxGeneration  = 100;
                populationSize = 500;
                crossoverRate = 0.6;
                mutateRate = 0.001;
            }
            
            public static void main(String[] args)throws IOException{

                FileWriter fw = new FileWriter("result.txt");
                BufferedWriter bw = new BufferedWriter(fw);
                PrintWriter pw = new PrintWriter(bw);
                
                Population pop = new Population(populationSize);
                pop.initPopulation();

                pw.println("初始种群:\n" + pop);
                while(!pop.isEvolutionDone()){
                    pop.evolve();
                    pw.print("第" + pop.getGeneration() + "代Best:" + pop.bestIndividual );
                    pw.print("第" + pop.getGeneration()  + "代current:" + pop.currentBest );
                    pw.println("");        
                }
                pw.println();
                pw.println("第"+ pop.getGeneration()  + "代群体:\n" + pop);

                pw.close();
            }
            
            public void print(){

            }
        }

    【Reference】
    [1]《遗传算法原理及应用》(周明、孙树栋编著)

    【Attachment】
  • 相关阅读:
    设计模式13---设计模式之观察者模式(Observer)(行为型)
    codeforces 166C Median
    HDU 1176 免费馅饼
    老鸟的Python新手教程
    setsockopt()使用方法(參数具体说明)
    RelativeLayout经常使用属性介绍
    java多线程模拟生产者消费者问题,公司面试常常问的题。。。
    JAVA实现HTTPserver端
    进程间通信_03命名管道
    expdp&amp;impdp
  • 原文地址:https://www.cnblogs.com/wintys/p/genetic_algorithms.html
Copyright © 2020-2023  润新知