[原]遗传算法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
【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;
}
}
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;
}
}
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();
}
}
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;
}
}
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(){
}
}
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】
作者:wintys (wintys@gmail.com)
出处:http://wintys.cnblogs.com
欢迎转载,转载请注明作者及出处。