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



【Content】:

1、简介

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


2、类图

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


 

 




java tsp 遗传算法 遗传算法java代码_i++

   (类图)


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】

[1] 《遗传算法原理及应用》(周明、孙树栋编著)
[2]遗传算法Java源代码