【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

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

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

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】

java 遗传算法_[原]遗传算法Java实现源代码相关推荐

  1. java 枚举_深入理解Java枚举

    所有知识体系文章,[GitHub](https://github.com/Ziphtracks/JavaLearningmanual)已收录,欢迎Star!再次感谢,愿你早日进入大厂! https:/ ...

  2. java学习_都说Java难学,不知道具体的学习内容?全套Java学习路线送上

    首先,我个人比较推崇的学习方法是:先学java前段,也就是HTML,css,js,因为学习java以后肯定是往java ee方向发展的,学习完前端,在学习后端很多东西比计较容易理解! 其中J2SE是关 ...

  3. exchange java对象,【原】Java并发程序的一个应用Exchanger的实例

    [原]Java并发程序的一个使用Exchanger的实例 今天看了些Exchanger的资料,有个喝水的例子不错.我这里细化了以下,并得到实现. 思路: 有一个Drinker和一个Waiter,有两个 ...

  4. pat上写java程序_如何运行Java程序和设置CLASSPAT

    导读: 如何运行JAVA和CLASSPATH环境变量的设置是学习和使用JAVA中最基本的问题,本不应在此赘述.但近来不少人在论坛上提出的问题却与此有关,我平时碰到的一些初学者也往往在这个问题上卡了壳, ...

  5. jcreator把class字节码文件转成.java源文件_如何将.JAVA文件编译成.CLASS文件.说明方法和工具,或用JCreator如何操作?...

    http://www.newiter.com/showart.asp?id=33 由于比较长,建议点击上面链接进入继续浏览 对于很多应用系统,常常需要动态装载和执行类和代码片断,这有利于部署的简易性和 ...

  6. groovy 使用java类_深入学习java中的Groovy 和 Scala 类

    前言 Java 传承的是平台,而不是语言.有超过 200 种语言可以在 JVM 上运行,它们之中不可避免地会有一种语言最终将取代 Java 语言,成为编写 JVM 程序的最佳方式.本系列将探讨三种下一 ...

  7. java娘_如何调教Java娘来优化MC!

    直入主题! UP最近发现了一个工具--Java Argument Generator[Java参数生成器] 那...什么是Java参数呢? --对于MC来说,Java参数就是电脑在告诉Java,运行游 ...

  8. java序列化_深入学习Java序列化

    前言 对于Java的序列化,一直只知道只需要实现Serializbale这个接口就可以了,具体内部实现一直不是很了解,正好这次在重复造RPC的轮子的时候涉及到序列化问题,就抽时间看了下 Java序列化 ...

  9. java安装_在线学习Java编程的最佳方法

    java安装 1.简介 Java是使用最广泛的编程语言之一. 根据Github的最新报告,Java被列为仅次于JavaScript的第二大最常用的编程语言. 掌握Java的人有很多话题. 好消息是,您 ...

最新文章

  1. VS2012设置断点的方法
  2. java,验证码base64编码到json字符串出显数据一行一行的问题,关于base64编码函数解释
  3. 中国 GDP 20 强城市排行榜(2001-2020)
  4. 【转】Visual Studio 2005 上 AJAX(AjaxControlToolkit) 的安装
  5. 怎么将短连接修改为长连接_回音壁怎么选?Redmi这个还不错
  6. [转]Windows Shell 编程 第五章 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7987939】...
  7. 开源组件分析工具OpenSCA教程
  8. 第九部分 项目沟通管理
  9. mysql当查询条件为空时不作为条件查询
  10. ASO新手快速入门教程
  11. pulsar client jar包选择-shaded 还是original
  12. 华夏第一都城《禹州市》
  13. Android 属性动画使用(二)
  14. Xshell4连接Linux后 win快捷键锁屏
  15. Windows 10 磁盘重新分区
  16. PCB设计3W、20H、五五规则
  17. C++ 魔兽世界之二:装备
  18. elementUi设置表格分页排序
  19. 使用httpclient时报错NoHttpResponseException failed to respond
  20. 诚之和:虚假滤镜、照骗风波,小红书到底得了什么病?

热门文章

  1. python模拟qq空间登录_python selenium模拟登录163邮箱和QQ空间
  2. 【Python基础知识-pycharm版】第一节-基础
  3. InfluxDB安装及使用
  4. python randint什么分布_python随机数分布random测试
  5. 史上最大多模态图文数据集发布!
  6. 从零搭建基于知识图谱的问答系统(以医疗行业为例)
  7. one-hot(独热)、bag of word(词袋)、word-Embedding(词嵌入)浅析
  8. 对话系统聊天机器人的设计艺术(上)
  9. 基于Consul的分布式信号量实现
  10. 阿里架构师进阶23期精讲:Redis、Kafka、Dubbo、Docker等