转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/50277547

http://www.llwjy.com/blogdetail/8d8f9fa295e57c774c2b8223166aee1b.html

个人博客站已经上线了,网址 www.llwjy.com ~欢迎各位吐槽~

-------------------------------------------------------------------------------------------------

关于遗传算法的详细原理以及具体的定义这里就不多介绍,想了解的可以自行百度,下面就简单介绍下自己对遗传算法的理解,本文对基因的编码采用二进制规则。

算法思想:

遗传算法参照达尔文的进化论,认为物种都是向好的方向去发展(适者生存),因此可以认为到足够的代数之后,得到的最值可实际的最值很接近。

算法步骤:

1)随机产生一个种群;
2)计算种群的适应度、最好适应度、最差适应度、平均适应度等指标;
3)验证种群代数是否达到自己设置的阈值,如果达到结束计算,否则继续下一步计算;
4)采用转盘赌法选择可以产生下一代的父代,产生下一代种群(种群中个体数量不变);
5)种群发生基因突变;
6)重复2、3、4、5步。

算法实现-基因部分

1、种群个体(这里认为是染色体),在个体中,我们为这个个体添加两个属性,个体的基因和基因对应的适应度(函数值)。

public class Chromosome {private boolean[] gene;//基因序列private double score;//对应的函数得分
}

2、随机生成基因序列,基因的每一个位置是0还是1,这里采用完全随机的方式实现。

public Chromosome(int size) {if (size <= 0) {return;}initGeneSize(size);for (int i = 0; i < size; i++) {gene[i] = Math.random() >= 0.5;}
}private void initGeneSize(int size) {if (size <= 0) {return;}gene = new boolean[size];
}

3、把基因转化为对应的值,比如101对应的数字是5,这里采用位运算来实现。

public int getNum() {if (gene == null) {return 0;}int num = 0;for (boolean bool : gene) {num <<= 1;if (bool) {num += 1;}}return num;
}

4、基因发生变异,对于变异的位置这里完全采取随机的方式实现,变异原则是由1变为0,0变为1。

public void mutation(int num) {//允许变异int size = gene.length;for (int i = 0; i < num; i++) {//寻找变异位置int at = ((int) (Math.random() * size)) % size;//变异后的值boolean bool = !gene[at];gene[at] = bool;}
}

5、克隆基因,用于产生下一代,这一步就是将已存在的基因copy一份。

public static Chromosome clone(final Chromosome c) {if (c == null || c.gene == null) {return null;}Chromosome copy = new Chromosome();copy.initGeneSize(c.gene.length);for (int i = 0; i < c.gene.length; i++) {copy.gene[i] = c.gene[i];}return copy;
}

6、父母双方产生下一代,这里两个个体产生两个个体子代,具体哪段基因差生交叉,完全随机。

public static List<Chromosome> genetic(Chromosome p1, Chromosome p2) {if (p1 == null || p2 == null) { //染色体有一个为空,不产生下一代return null;}if (p1.gene == null || p2.gene == null) { //染色体有一个没有基因序列,不产生下一代return null;}if (p1.gene.length != p2.gene.length) { //染色体基因序列长度不同,不产生下一代return null;}Chromosome c1 = clone(p1);Chromosome c2 = clone(p2);//随机产生交叉互换位置int size = c1.gene.length;int a = ((int) (Math.random() * size)) % size;int b = ((int) (Math.random() * size)) % size;int min = a > b ? b : a;int max = a > b ? a : b;//对位置上的基因进行交叉互换for (int i = min; i <= max; i++) {boolean t = c1.gene[i];c1.gene[i] = c2.gene[i];c2.gene[i] = t;}List<Chromosome> list = new ArrayList<Chromosome>();list.add(c1);list.add(c2);return list;
}

算法实现-遗传算法

1、对于遗传算法,我们需要有对应的种群以及我们需要设置的一些常量:种群数量、基因长度、基因突变个数、基因突变率等,具体参照如下代码:

public abstract class GeneticAlgorithm {private List<Chromosome> population = new ArrayList<Chromosome>();//种群private int popSize = 100;//种群数量private int geneSize;//基因最大长度private int maxIterNum = 500;//最大迭代次数private double mutationRate = 0.01;//基因变异的概率private int maxMutationNum = 3;//最大变异步长private int generation = 1;//当前遗传到第几代private double bestScore;//最好得分private double worstScore;//最坏得分private double totalScore;//总得分private double averageScore;//平均得分private double x; //记录历史种群中最好的X值private double y; //记录历史种群中最好的Y值private int geneI;//x y所在代数
}

2、初始化种群,在遗传算法开始时,我们需要初始化一个原始种群,这就是原始的第一代。

private void init() {population = new ArrayList<Chromosome>();for (int i = 0; i < popSize; i++) {Chromosome chro = new Chromosome(geneSize);population.add(chro);}caculteScore();
}

3、在初始种群存在后,我们需要计算种群的适应度以及最好适应度、最坏适应度和平均适应度等。

private void caculteScore() {setChromosomeScore(population.get(0));bestScore = population.get(0).getScore();worstScore = population.get(0).getScore();totalScore = 0;for (Chromosome chro : population) {setChromosomeScore(chro);if (chro.getScore() > bestScore) { //设置最好基因值bestScore = chro.getScore();if (y < bestScore) {x = changeX(chro);y = bestScore;geneI = generation;}}if (chro.getScore() < worstScore) { //设置最坏基因值worstScore = chro.getScore();}totalScore += chro.getScore();}averageScore = totalScore / popSize;//因为精度问题导致的平均值大于最好值,将平均值设置成最好值averageScore = averageScore > bestScore ? bestScore : averageScore;
}

4、在计算个体适应度的时候,我们需要根据基因计算对应的Y值,这里我们设置两个抽象方法,具体实现由类的实现去实现。

private void setChromosomeScore(Chromosome chro) {if (chro == null) {return;}double x = changeX(chro);double y = caculateY(x);chro.setScore(y);}/*** @param chro* @return* @Author:lulei  * @Description: 将二进制转化为对应的X*/
public abstract double changeX(Chromosome chro);/*** @param x* @return* @Author:lulei  * @Description: 根据X计算Y值 Y=F(X)*/
public abstract double caculateY(double x);

5、在计算完种群适应度之后,我们需要使用转盘赌法选取可以产生下一代的个体,这里有个条件就是只有个人的适应度不小于平均适应度才会长生下一代(适者生存)。

private Chromosome getParentChromosome (){double slice = Math.random() * totalScore;double sum = 0;for (Chromosome chro : population) {sum += chro.getScore();//转到对应的位置并且适应度不小于平均适应度if (sum > slice && chro.getScore() >= averageScore) {return chro;}}return null;
}

6、选择可以产生下一代的个体之后,就要交配产生下一代

private void evolve() {List<Chromosome> childPopulation = new ArrayList<Chromosome>();//生成下一代种群while (childPopulation.size() < popSize) {Chromosome p1 = getParentChromosome();Chromosome p2 = getParentChromosome();List<Chromosome> children = Chromosome.genetic(p1, p2);if (children != null) {for (Chromosome chro : children) {childPopulation.add(chro);}} }//新种群替换旧种群List<Chromosome> t = population;population = childPopulation;t.clear();t = null;//基因突变mutation();//计算新种群的适应度caculteScore();
}

7、在产生下一代的过程中,可能会发生基因变异

private void mutation() {for (Chromosome chro : population) {if (Math.random() < mutationRate) { //发生基因突变int mutationNum = (int) (Math.random() * maxMutationNum);chro.mutation(mutationNum);}}
}

8、将上述步骤一代一代的重复执行

public void caculte() {//初始化种群generation = 1;init();while (generation < maxIterNum) {//种群遗传evolve();print();generation++;}
}

编写实现类

由于上述遗传算法的类是一个抽象类,因此我们需要针对特定的事例编写实现类,假设我们计算 Y=100-log(X)在[6,106]上的最值。

1、我们假设基因的长度为24(基因的长度由要求结果的有效长度确定),因此对应的二进制最大值为 1<< 24,我们做如下设置

public class GeneticAlgorithmTest extends GeneticAlgorithm{public static final int NUM = 1 << 24;public GeneticAlgorithmTest() {super(24);  }
}

2、对X值的抽象方法进行实现

@Override
public double changeX(Chromosome chro) {// TODO Auto-generated method stub  return ((1.0 * chro.getNum() / NUM) * 100) + 6;
}

3、对Y的抽象方法进行实现

@Override
public double caculateY(double x) {// TODO Auto-generated method stub  return 100 - Math.log(x);
}

运行结果

遗传算法思考

自己看了很多遗传算法的介绍,上面提到的最优解都是最后一代的最值,自己就有一个疑问了,为什么我知道前面所有带中的最值,也就是程序中的X  Y值,为什么不能用X Y值做遗传算法最后的结果值呢?

完整代码

1、Chromosome类

 /**  *@Description: 基因遗传染色体   */
package com.lulei.genetic.algorithm;  import java.util.ArrayList;
import java.util.List;public class Chromosome {private boolean[] gene;//基因序列private double score;//对应的函数得分public double getScore() {return score;}public void setScore(double score) {this.score = score;}/*** @param size* 随机生成基因序列*/public Chromosome(int size) {if (size <= 0) {return;}initGeneSize(size);for (int i = 0; i < size; i++) {gene[i] = Math.random() >= 0.5;}}/*** 生成一个新基因*/public Chromosome() {}/*** @param c* @return* @Author:lulei  * @Description: 克隆基因*/public static Chromosome clone(final Chromosome c) {if (c == null || c.gene == null) {return null;}Chromosome copy = new Chromosome();copy.initGeneSize(c.gene.length);for (int i = 0; i < c.gene.length; i++) {copy.gene[i] = c.gene[i];}return copy;}/*** @param size* @Author:lulei  * @Description: 初始化基因长度*/private void initGeneSize(int size) {if (size <= 0) {return;}gene = new boolean[size];}/*** @param c1* @param c2* @Author:lulei  * @Description: 遗传产生下一代*/public static List<Chromosome> genetic(Chromosome p1, Chromosome p2) {if (p1 == null || p2 == null) { //染色体有一个为空,不产生下一代return null;}if (p1.gene == null || p2.gene == null) { //染色体有一个没有基因序列,不产生下一代return null;}if (p1.gene.length != p2.gene.length) { //染色体基因序列长度不同,不产生下一代return null;}Chromosome c1 = clone(p1);Chromosome c2 = clone(p2);//随机产生交叉互换位置int size = c1.gene.length;int a = ((int) (Math.random() * size)) % size;int b = ((int) (Math.random() * size)) % size;int min = a > b ? b : a;int max = a > b ? a : b;//对位置上的基因进行交叉互换for (int i = min; i <= max; i++) {boolean t = c1.gene[i];c1.gene[i] = c2.gene[i];c2.gene[i] = t;}List<Chromosome> list = new ArrayList<Chromosome>();list.add(c1);list.add(c2);return list;}/*** @param num* @Author:lulei  * @Description: 基因num个位置发生变异*/public void mutation(int num) {//允许变异int size = gene.length;for (int i = 0; i < num; i++) {//寻找变异位置int at = ((int) (Math.random() * size)) % size;//变异后的值boolean bool = !gene[at];gene[at] = bool;}}/*** @return* @Author:lulei  * @Description: 将基因转化为对应的数字*/public int getNum() {if (gene == null) {return 0;}int num = 0;for (boolean bool : gene) {num <<= 1;if (bool) {num += 1;}}return num;}
}

2、GeneticAlgorithm类

 /**  *@Description:     */
package com.lulei.genetic.algorithm;  import java.util.ArrayList;
import java.util.List;public abstract class GeneticAlgorithm {private List<Chromosome> population = new ArrayList<Chromosome>();private int popSize = 100;//种群数量private int geneSize;//基因最大长度private int maxIterNum = 500;//最大迭代次数private double mutationRate = 0.01;//基因变异的概率private int maxMutationNum = 3;//最大变异步长private int generation = 1;//当前遗传到第几代private double bestScore;//最好得分private double worstScore;//最坏得分private double totalScore;//总得分private double averageScore;//平均得分private double x; //记录历史种群中最好的X值private double y; //记录历史种群中最好的Y值private int geneI;//x y所在代数public GeneticAlgorithm(int geneSize) {this.geneSize = geneSize;}public void caculte() {//初始化种群generation = 1;init();while (generation < maxIterNum) {//种群遗传evolve();print();generation++;}}/*** @Author:lulei  * @Description: 输出结果*/private void print() {System.out.println("--------------------------------");System.out.println("the generation is:" + generation);System.out.println("the best y is:" + bestScore);System.out.println("the worst fitness is:" + worstScore);System.out.println("the average fitness is:" + averageScore);System.out.println("the total fitness is:" + totalScore);System.out.println("geneI:" + geneI + "\tx:" + x + "\ty:" + y);}/*** @Author:lulei  * @Description: 初始化种群*/private void init() {for (int i = 0; i < popSize; i++) {population = new ArrayList<Chromosome>();Chromosome chro = new Chromosome(geneSize);population.add(chro);}caculteScore();}/*** @Author:lulei  * @Description:种群进行遗传*/private void evolve() {List<Chromosome> childPopulation = new ArrayList<Chromosome>();//生成下一代种群while (childPopulation.size() < popSize) {Chromosome p1 = getParentChromosome();Chromosome p2 = getParentChromosome();List<Chromosome> children = Chromosome.genetic(p1, p2);if (children != null) {for (Chromosome chro : children) {childPopulation.add(chro);}} }//新种群替换旧种群List<Chromosome> t = population;population = childPopulation;t.clear();t = null;//基因突变mutation();//计算新种群的适应度caculteScore();}/*** @return* @Author:lulei  * @Description: 轮盘赌法选择可以遗传下一代的染色体*/private Chromosome getParentChromosome (){double slice = Math.random() * totalScore;double sum = 0;for (Chromosome chro : population) {sum += chro.getScore();if (sum > slice && chro.getScore() >= averageScore) {return chro;}}return null;}/*** @Author:lulei  * @Description: 计算种群适应度*/private void caculteScore() {setChromosomeScore(population.get(0));bestScore = population.get(0).getScore();worstScore = population.get(0).getScore();totalScore = 0;for (Chromosome chro : population) {setChromosomeScore(chro);if (chro.getScore() > bestScore) { //设置最好基因值bestScore = chro.getScore();if (y < bestScore) {x = changeX(chro);y = bestScore;geneI = generation;}}if (chro.getScore() < worstScore) { //设置最坏基因值worstScore = chro.getScore();}totalScore += chro.getScore();}averageScore = totalScore / popSize;//因为精度问题导致的平均值大于最好值,将平均值设置成最好值averageScore = averageScore > bestScore ? bestScore : averageScore;}/*** 基因突变*/private void mutation() {for (Chromosome chro : population) {if (Math.random() < mutationRate) { //发生基因突变int mutationNum = (int) (Math.random() * maxMutationNum);chro.mutation(mutationNum);}}}/*** @param chro* @Author:lulei  * @Description: 设置染色体得分*/private void setChromosomeScore(Chromosome chro) {if (chro == null) {return;}double x = changeX(chro);double y = caculateY(x);chro.setScore(y);}/*** @param chro* @return* @Author:lulei  * @Description: 将二进制转化为对应的X*/public abstract double changeX(Chromosome chro);/*** @param x* @return* @Author:lulei  * @Description: 根据X计算Y值 Y=F(X)*/public abstract double caculateY(double x);public void setPopulation(List<Chromosome> population) {this.population = population;}public void setPopSize(int popSize) {this.popSize = popSize;}public void setGeneSize(int geneSize) {this.geneSize = geneSize;}public void setMaxIterNum(int maxIterNum) {this.maxIterNum = maxIterNum;}public void setMutationRate(double mutationRate) {this.mutationRate = mutationRate;}public void setMaxMutationNum(int maxMutationNum) {this.maxMutationNum = maxMutationNum;}public double getBestScore() {return bestScore;}public double getWorstScore() {return worstScore;}public double getTotalScore() {return totalScore;}public double getAverageScore() {return averageScore;}public double getX() {return x;}public double getY() {return y;}
}

3、GeneticAlgorithmTest类

 /**  *@Description:     */
package com.lulei.genetic.algorithm;  public class GeneticAlgorithmTest extends GeneticAlgorithm{public static final int NUM = 1 << 24;public GeneticAlgorithmTest() {super(24);  }@Overridepublic double changeX(Chromosome chro) {// TODO Auto-generated method stub  return ((1.0 * chro.getNum() / NUM) * 100) + 6;}@Overridepublic double caculateY(double x) {// TODO Auto-generated method stub  return 100 - Math.log(x);}public static void main(String[] args) {GeneticAlgorithmTest test = new GeneticAlgorithmTest();test.caculte();}
}

-------------------------------------------------------------------------------------------------
小福利
-------------------------------------------------------------------------------------------------
      个人在极客学院上《Lucene案例开发》课程已经上线了(目前上线到第二课),欢迎大家吐槽~

第一课:Lucene概述

第二课:Lucene 常用功能介绍

第三课:网络爬虫

第四课:数据库连接池

第五课:小说网站的采集

第六课:小说网站数据库操作

第七课:小说网站分布式爬虫的实现

JAVA实现遗传算法相关推荐

  1. java tsp 遗传算法_遗传算法解决TSP问题

    1实验环境 实验环境:CPU i5-2450M@2.50GHz,内存6G,windows7 64位操作系统 实现语言:java (JDK1.8) 实验数据:TSPLIB,TSP采样实例库中的att48 ...

  2. java matlab 遗传算法_简单遗传算法MATLAB实现

    遗传算法的概念最早是由Bagley J.D 于1967年提出的.后来Michigan大学的J.H.Holland教授于1975年开始对遗传算法(Genetic Algorithm, GA)的机理进行系 ...

  3. java 用遗传算法解决图像二值化问题 找阈值

    image类对图像处理 import java.awt.image.BufferedImage; public class Image {public int h; //高public int w; ...

  4. Java使用遗传算法实现智能组卷

    遗传算法实现智能组卷 0.需求:用户选择知识点.年级.难度系数.题型.题目总数量,一键智能生成试卷,如下 1.遗传算法: 1.0 参考博文: 理论概念详解:https://www.jianshu.co ...

  5. java遗传算法编程_遗传算法示例程序

    评论 # re: 遗传算法示例程序  回复  更多评论 2007-05-06 00:18 by 橙子的希望 我可不可以表示晕倒? # re: 遗传算法示例程序[未登录]  回复  更多评论 2007- ...

  6. Genetic Algorithm遗传算法,两个代码实现例子

    通过了解遗传算法的概念,应用和代码实现,来充分理解和学习遗传算法.本文文末包含两个不同的通俗易懂的例子,分别使用java和python实现. 什么是遗传算法? 可参考这篇文章:link 应用:List ...

  7. 计算机专业毕业设计—JAVA语言系统设计(共80套打包)

    JAVA SMART系统-系统框架设计与开发(源代码+论文).rar java Smart系统-题库及试卷管理模块的设计与开发(源代码+论文) java Smart系统-题库及试卷管理模块的设计与开发 ...

  8. 【运筹优化】求解TSP问题的算法合辑 + Java代码实现

    文章目录 一.算法合辑 1.1 SA模拟退火算法 1.2 TS禁忌搜索算法 1.3 ACO蚁群算法 1.4 GA遗传算法 1.5 ILS迭代局部搜索算法 1.6 VNS变邻域搜索算法 1.7 ALNS ...

  9. 基于遗传算法的排课算法思路

    摘自毕业论文<基于微服务的智能教学质量管理平台的设计与实现> (1)问题描述 课程编排(排课)是平台的核心功能.排课问题被国外专家证明为属于NP完全问题,本质是求出满足一定软硬约束下的教学 ...

最新文章

  1. C语言新手写扫雷攻略3
  2. 计算 sigmoid 函数的导数
  3. Go 语言新提案:添加模糊测试支持
  4. html偷拍代码,一段植入木马的html代码
  5. android邮件发送几种方式
  6. json怎么读取数据库_如何:使用Json插入数据库并从中读取
  7. 【C语言进阶深度学习记录】十二 C语言中的:字符和字符串
  8. 【es】es 集群黄色几个索引未分配 timed out waiting for all nodes to published state
  9. MongoDB管理与监控
  10. 感谢第一个和第二个付费客户对我的信任
  11. 算法设计与分析(屈婉玲)pdf
  12. Overfeat模型(滑动窗口)
  13. 计算机一级三维饼图,计算机考试excel制作复合饼图的方法
  14. 如何制作简单的日历html5,js+html制作简单日历的方法
  15. 搜图出处的软件_以图搜图搜gif图片出处来源的懒人小工具
  16. 微信公众平台基本功能简单说明
  17. Havel_Theorem
  18. 真有人去炸公司了...
  19. ResNet 阅读学习和实现
  20. Git 如何把master的内容更新到分支

热门文章

  1. 全国电话订票95105105
  2. 原来 Clipboard 还能复制图像?原理是什么
  3. 【机器学习实战】使用sklearn中的决策树对红酒数据集进行分类(Jupyter)
  4. 芸赞通天下沈扬舍己为人亮风采
  5. Android应用中平滑的手写效果实现
  6. 矩阵乘法之叉乘和点乘
  7. CiteSpace导入WOS数据详细步骤
  8. ​​​​​​​《MYSQL高级查询与编程》综合机试试卷 - 云南农职美和易思
  9. 欧式简约互联网科技PPT模板
  10. STM32F1_SysTick系统滴答