java 遗传算法_[原]遗传算法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
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实现源代码相关推荐
- java 枚举_深入理解Java枚举
所有知识体系文章,[GitHub](https://github.com/Ziphtracks/JavaLearningmanual)已收录,欢迎Star!再次感谢,愿你早日进入大厂! https:/ ...
- java学习_都说Java难学,不知道具体的学习内容?全套Java学习路线送上
首先,我个人比较推崇的学习方法是:先学java前段,也就是HTML,css,js,因为学习java以后肯定是往java ee方向发展的,学习完前端,在学习后端很多东西比计较容易理解! 其中J2SE是关 ...
- exchange java对象,【原】Java并发程序的一个应用Exchanger的实例
[原]Java并发程序的一个使用Exchanger的实例 今天看了些Exchanger的资料,有个喝水的例子不错.我这里细化了以下,并得到实现. 思路: 有一个Drinker和一个Waiter,有两个 ...
- pat上写java程序_如何运行Java程序和设置CLASSPAT
导读: 如何运行JAVA和CLASSPATH环境变量的设置是学习和使用JAVA中最基本的问题,本不应在此赘述.但近来不少人在论坛上提出的问题却与此有关,我平时碰到的一些初学者也往往在这个问题上卡了壳, ...
- jcreator把class字节码文件转成.java源文件_如何将.JAVA文件编译成.CLASS文件.说明方法和工具,或用JCreator如何操作?...
http://www.newiter.com/showart.asp?id=33 由于比较长,建议点击上面链接进入继续浏览 对于很多应用系统,常常需要动态装载和执行类和代码片断,这有利于部署的简易性和 ...
- groovy 使用java类_深入学习java中的Groovy 和 Scala 类
前言 Java 传承的是平台,而不是语言.有超过 200 种语言可以在 JVM 上运行,它们之中不可避免地会有一种语言最终将取代 Java 语言,成为编写 JVM 程序的最佳方式.本系列将探讨三种下一 ...
- java娘_如何调教Java娘来优化MC!
直入主题! UP最近发现了一个工具--Java Argument Generator[Java参数生成器] 那...什么是Java参数呢? --对于MC来说,Java参数就是电脑在告诉Java,运行游 ...
- java序列化_深入学习Java序列化
前言 对于Java的序列化,一直只知道只需要实现Serializbale这个接口就可以了,具体内部实现一直不是很了解,正好这次在重复造RPC的轮子的时候涉及到序列化问题,就抽时间看了下 Java序列化 ...
- java安装_在线学习Java编程的最佳方法
java安装 1.简介 Java是使用最广泛的编程语言之一. 根据Github的最新报告,Java被列为仅次于JavaScript的第二大最常用的编程语言. 掌握Java的人有很多话题. 好消息是,您 ...
最新文章
- VS2012设置断点的方法
- java,验证码base64编码到json字符串出显数据一行一行的问题,关于base64编码函数解释
- 中国 GDP 20 强城市排行榜(2001-2020)
- 【转】Visual Studio 2005 上 AJAX(AjaxControlToolkit) 的安装
- 怎么将短连接修改为长连接_回音壁怎么选?Redmi这个还不错
- [转]Windows Shell 编程 第五章 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7987939】...
- 开源组件分析工具OpenSCA教程
- 第九部分 项目沟通管理
- mysql当查询条件为空时不作为条件查询
- ASO新手快速入门教程
- pulsar client jar包选择-shaded 还是original
- 华夏第一都城《禹州市》
- Android 属性动画使用(二)
- Xshell4连接Linux后 win快捷键锁屏
- Windows 10 磁盘重新分区
- PCB设计3W、20H、五五规则
- C++ 魔兽世界之二:装备
- elementUi设置表格分页排序
- 使用httpclient时报错NoHttpResponseException failed to respond
- 诚之和:虚假滤镜、照骗风波,小红书到底得了什么病?
热门文章
- python模拟qq空间登录_python selenium模拟登录163邮箱和QQ空间
- 【Python基础知识-pycharm版】第一节-基础
- InfluxDB安装及使用
- python randint什么分布_python随机数分布random测试
- 史上最大多模态图文数据集发布!
- 从零搭建基于知识图谱的问答系统(以医疗行业为例)
- one-hot(独热)、bag of word(词袋)、word-Embedding(词嵌入)浅析
- 对话系统聊天机器人的设计艺术(上)
- 基于Consul的分布式信号量实现
- 阿里架构师进阶23期精讲:Redis、Kafka、Dubbo、Docker等