遗传算法的基本概念和实现(附 Java 实现案例)
基因遗传算法借鉴了达尔文自然进化的思想,是一种启发式搜索方法。它模拟了自然界中的选择机制,表现最优秀的个体能够繁衍后代。本文概述了遗传算法的核心原理和具体应用,旨在让读者领略到启发式搜索的独特之处。
如左侧图像所示,遗传算法中的个体包含若干条染色体,每条染色体又由多个基因构成。右侧图像呈现了染色体的分割与重组模式。
自然选择的概念
自然选择首先挑选出最适应环境的群体成员,后代会遗传双亲的性状,这些性状会传递给下一代,如果双亲更具生存优势,它们的子代就更容易存活,不断重复这种自然选择过程,最终会形成全部由最适应环境的个体构成的一代。
这种思路能够运用到查找任务上。我们会审视某个议题的各种可能答案,然后挑选出最合适的那个。
遗传算法含以下五步:
初始化
个体评价(计算适应度函数)
选择运算
交叉运算
变异运算
初始化
这个流程以种群中若干个体为起点,每个个体都是针对待解问题的一个可能方案,用以尝试找到最优解。
一个生命体由一系列数值来描述其特性,这些数值被称为基因,多个基因按顺序排列形成一条链,这条链就是染色体,它代表了解决某个问题的方案。
遗传算法里,每个个体的基因序列用字符序列表达,一般采用二进制形式,就是用由1和0构成的序列来表示染色体。这样开元ky888棋牌官方版,基因序列或者备选方案的特性就被我们记录在染色体上了。
种群、染色体和基因
个体评估借助适应度函数衡量其与环境相契合的程度,也体现与其他个体角逐的优劣。每个个体都获得适应度等级,被挑选参与繁衍的机会与其等级高低相关。适应度数值越高,代表方案品质越佳。适应度函数充当遗传算法演化的核心动力,同时也是自然选择的主要依据,它的构建需要依据具体问题的特性来制定。
选择运算
挑选出来的目标是为了让那些最为匹配的个体能够繁衍后代,并将自身的遗传信息传递给下一代。根据它们各自所获得的评价等级,我们会挑选出许多对较为出色的配对组合。那些评价分数较高的个体,被选中的几率会更大,也就是说,这些优秀父母的遗传特征会遗传给下一代。
交叉运算
遗传算法里,交叉是最核心的一步,针对每一对配偶,基因都有随机选定的结合位置。
举个例子,下图的交叉点为3。
父母间在交叉点之前交换基因,从而产生了后代。
父母间交换基因,然后产生的新后代被添加到种群中。
变异运算
部分新生后代里,其部分基因或许会遭遇低频变异因素影响,造成二进制序列里某些位发生转变。
变异运算前后
变异运算可用于保持种群内的多样性,并防止过早收敛。
终止
当集体趋向稳定时,即集体成员之间不再产生与上一代相比差异显著的后代,该算法便会结束运行,这表明遗传算法能够给出一组针对特定问题的解决方案。
案例实现
群体数量保持稳定。新的一代出现时,那些最不合适的个体会消亡,从而为下一代腾出位置。这种过程按顺序不断循环,目的是创造出比以往更出色的新一代。
这一迭代过程的伪代码:
START
形成初始种群,包含多个个体,每个个体都是随机生成的,通过编码表示其基因信息,随后进入进化过程,用于后续的优化和迭代
Compute fitness
REPEAT
Selection
Crossover
Mutation
Compute fitness
直至人口趋于一致
STOP
Java中的示例实现
这里呈现的是遗传算法在Java语言中的具体编写过程,允许对代码进行任意调整和改动。一个基因序列由五个基因构成,每个基因能够记录二进制数据0或1。当前的评价标准是基因序列里1的个数。当基因序列包含五个1时,该生物体的评价值最高。当基因序列完全由0组成时,该生物体的评价值最低。这个遗传算法致力于提升适配度,并生成由适配度最优的个体构成的集合。需要留意的是,在此情形下,经过配对繁衍和基因变异之后,适配度最差的成员会被适配度最优异的后代所取代。
import java.util.Random;
/**
* @author Vijini
*/
//Main class
public class SimpleDemoGA {
个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例个体实例
Individual fittest;
Individual secondFittest;
int generationCount = 0;
启动主程序,执行以下操作,在Java环境中运行,创建一个名为main的方法,参数类型为String数组,程序从这里开始执行任务,完成初始化设置,接着进行核心功能处理,最后结束运行过程。
args) {
Random rn = new Random();
SimpleDemoGA类型的demo实例被创建了,命名为demo
//Initialize population
初始化种群数量为十,通过demo.population方法,调用initializePopulation函数
评估每个个体的适应度,计算其表现,衡量其优劣
模拟生物的种群,计算其适应度值,用于评估表现
输出当前世代数量,即demo的世代计数,接着输出,种群中最适应者的信息,来自demo的种群对象
当群体中出现一个拥有最高适应度值的个体时
当演示种群中的最优个体,与此同时< 5) {
++demo.generationCount;
//Do selection
demo.selection();
//Do crossover
demo.crossover();
随机概率下进行变异
if (rn.nextInt()%7 < 5) {
demo.mutation();
挑选最优秀的后代加入群体中
demo.addFittestOffspring();
//Calculate new fitness value
demo.population.calculateFitness();
System.out.println("Generation: " + demo.generationCount + " Fittest: " + demo.population.fittest);
程序输出了,是在第几代找到了答案,具体是第demo.generationCount代。
输出最佳适应度值,该值来自种群中的最优个体,通过调用其适应度方法获得开yun体育官网入口登录app,整体过程通过系统输出语句实现
System.out.print("Genes: ");
for (int i = 0; i < 5; i++) {
系统输出演示种群中适应度最优个体的基因,这些基因通过比较得出最佳表现,最终被显示出来
);
System.out.println("");
//Selection
void selection() {
挑选出最适宜的那个个体
最佳个体 = 种群中获取最优秀者,
挑选出第二强的个体
secondFittest是个体群中次优的那个,通过调用getSecondFittest方法获得
//Crossover
void crossover() {
随机挑选一个交叉点
这个值等于随机数生成器在种群个体数组中的某个位置上取值的结果
.geneLength);
//Swap values among parents
for (int i = 0; i < crossOverPoint; i++) {
int temp = fittest.genes
fittest.genes
= secondFittest.genes
secondFittest.genes
= temp;
//Mutation
void mutation() {
随机挑选一个变异位点
变异点位置由随机数生成器决定,该生成器取值范围是种群个体数量之内,最终结果赋值给变量mutationPoint,作为标记
.geneLength);
在变异位置上颠倒数值,进行交换,完成操作
if (fittest.genes
mutationPoint
== 0) {
fittest.genes
mutationPoint
= 1;
} else {
突变点位置由随机数生成器决定,其数值范围在种群个体数量之内,最终结果赋值给变量突变点
.geneLength);
if (secondFittest.genes
mutationPoint
== 0) {
secondFittest.genes
mutationPoint
= 1;
//Get fittest offspring
某个体获得最适宜后代(),通过评估适应度(),选择优良基因(),结合繁殖策略(),产生新个体(),并比较其表现(),最终确定最优后代()。
当最适宜个体的适应度值高于次适宜个体的适应度值时,
return fittest;
return secondFittest;
淘汰最弱的后代,选择最强的后代进行替换
void addFittestOffspring() {
更新子代健身值
fittest.calcFitness();
secondFittest.calcFitness();
找出最不合适个体的索引
当前种群中最劣个体索引值赋给 leastFittestIndex 变量,通过调用获取最小适应度索引的方法实现
//Replace least fittest individual from most fittest offspring
population.individuals
leastFittestIndex
= getFittestOffspring();
//Individual class
class Individual {
int fitness = 0;
int
genes = new int
int geneLength = 5;
public Individual() {
为每个独立体随机设定基因序列,采用随机方法,确保每个体基因不同
for (int i = 0; i < genes.length; i++) {
genes
= rn.nextInt() % 2;
fitness = 0;
//Calculate fitness
public void calcFitness() {
if (genes
== 1) {
++fitness;
//Population class
class Population {
int popSize = 10;
Individual
individuals = new Individual
10
int fittest = 0;
//Initialize population
创建种群函数接收大小参数,用于初始化个体集合,分配指定数量,生成初始种群结构,完成种群建立过程。
for (int i = 0; i < individuals.length; i++) {
individuals
= new Individual();
//Get the fittest individual
获取最适宜的个体,需要遍历全部个体,比较它们的适应度值,最后选出适应度值最高的那个个体作为最适宜的个体
最大适配值初始为最小整数值
if (maxFit individuals
maxFit1
.fitness) {
maxFit2 = maxFit1;
} else if (individuals
.fitness > individuals
maxFit2
.fitness) {
找出最不适应个体的索引,通过比较所有成员的适应度值,可以确定这个位置,这个个体在群体中的表现最差,需要被优先考虑替换,以便提升整个群体的适应水平
寻找最不适应的索引值开元ky888棋牌官网版,通过比较所有个体的适应度得分,确定数值最小者,该索引即为所求目标位置
int minFit = 0;
if (minFit >= individuals
.fitness) {
minFit = i;
return minFit;
//Calculate fitness of each individual
开放一个方法用以计算适配度,该方法名为calculateFitness
individuals
.calcFitness();
getFittest();