本文将向大家介绍遗传算法的工作原理,并将实现的遗传算法和功能进行优化。
遗传算法是一种基于搜索的优化技术。它通常用于查找最佳或最接近的最佳解决方案。它是由约翰·荷兰提出的。基于达尔文的自然选择理论,在解释遗传算法的工作原理之前,让我先解释达尔文的自然选择理论。在他的理论中,他将自然选择定义为“保留(特质)每一个细微变化(如果有用)的原则”。这个概念很简单但是很强大:最适合自己环境的个体更有可能生存和繁殖。有时将此理论描述为“适者生存”。那些比其他人更优秀的人有机会在这种进化中生存。遗传算法就是关于此的。它模仿自然选择的过程以找到最佳解决方案。
在遗传学中,我们将使用一些生物学术语,例如种群,染色体,基因,选择,交叉,突变。现在,首先,让我们尝试了解这些术语的含义。
人口,染色体,基因
在此过程的开始,我们需要初始化一些可能的解决方案。人口是给定问题的所有可能解决方案的子集。换句话说,我们可以说种群是一组染色体。染色体是解决当前问题的一种方法。每个染色体都是一组基因。
为简单起见,我们可以将染色体描述为字符串。因此,可以说总体是某个字符串的集合(每个字符都是二进制值,0或1)。字符串的每个字符都是一个基因。
为了开始遗传算法的过程,我们首先需要初始化种群。我们可以通过两种方式初始化总体。第一个是随机的,第二个是启发式的。最好从随机种群开始算法。
健身功能
初始化种群后,我们需要计算这些染色体的适应度值。现在的问题是这个适应度函数是什么以及它如何计算适应度值。
例如,假设我们有一个方程f(x)=-x²+5。我们需要具有最大值且约束为0≤x≤31的解。
现在,让我们假设我们有一个随机的四个染色体群体,如下所示。我们的染色体长度为5,因为2⁵= 32和0≤x≤31。
我们的适应度函数将按照问题陈述中所述计算每个染色体的功能值:
对于第1条染色体,01110表示整数14。因此,f(x)=-(14 * 14)+ 5 = -191。
对于第二条染色体,10101表示21的整数。因此,f(x)=-(21 * 21)+ 5 = -436。
对于第3条染色体,00011表示3的整数。因此,f(x)=-(3 * 3)+ 5 = -4。
对于第4条染色体,10111表示23的整数。因此,f(x)=-(23 * 23)+ 5 = -524。
家长选择
通过使用适应度函数计算出的染色体适应度值来进行亲本选择。基于这些适应度值,我们需要选择适应度值最高的一对染色体。
健身计算的方法有很多,例如轮盘赌轮选择,等级选择。
在轮盘赌选择中,适应性值最高的染色体最有可能被选为亲本。但是在此选择过程中,可以选择一个较低的值。
在等级选择中,根据染色体的适合度从高到低对染色体进行排名。例如,根据上面计算出的适应度值,我们可以按照从高到低的顺序对那些染色体进行排序,例如3rd> 1st> 2nd> 4th。因此,在选择阶段,将根据从适应度函数计算出的适应度值选择第3条和第1条染色体。
分频器
交叉用于通过产生子代或后代来改变染色体的编程,从一代到另一一代。亲本染色体用于产生这些后代(生成的染色体)。
为了产生后代,有一些方法,例如单点交叉,两点或多点交叉。
对于单点交叉,首先,我们需要选择一个点,然后将这些部分除以该点在亲本染色体之间交换以创建后代。您可以使用颜色组合以便于理解。
对于两点交叉,我们需要选择两个点,然后交换位。
最后,这些新的后代被添加到种群中。
突变
突变为人口带来多样性。有不同种类的突变,例如位翻转突变,交换突变,反转突变等。这些是如此简单。
在“位翻转”突变中,只需选择一个或多个位,然后翻转它们即可。如果所选位为0,则将其设置为1;如果所选位为1,则将其设置为0。
在交换位突变中,选择两个位并交换它们。
在逆突变中,只需逆位。
遗传算法在Python中的实现
让我们尝试在python中实现遗传算法以进行功能优化。
问题陈述
假设我们有一个方程,f(x)=-x²+ 5。我们需要具有最大值且约束为0≤x≤31的解决方案。要选择初始种群,请使用概率0.2。
您可以在此处找到完整的代码。
初始人口
随机初始化比启发式初始化更好。因此,这里将随机初始化用于填充初始化。
#initialize人口导入随机最好= -100000 种群=([[random.randint(0,1)对于x 在范围(6)]其中i 在范围(4)])的打印(类型(群体))父母= [] new_populations = [] 打印(人口)
健身功能
适应度函数计算染色体的适应度值。适应度功能的功能取决于问题的要求。
#fitness分数计算............ DEF fitness_score(): 全球人口,最好 fit_value = [] fit_score = [] 对于i 在范围(4): chromosome_value = 0 对于j 在范围(5 ,0,-1): 染色体值+ =群体[i] [j] *(2 **(5-j)) 染色体值= -1 *染色体值,如果群体[i] [0] == 1则染色体值 print(chromosome_value ) fit_value.append(-(chromosome_value ** 2)+ 5) print(fit_value) fit_value,人口= zip(* sorted(zip(fit_value,人口,反向= True)) best = fit_value [0] Fitness_score()
选拔
根据适合度分数选择最适合的染色体。这里使用等级选择过程。
def selectparent(): 全球父母 #全球人口,父母 parents =人口[0:2] print(type(parents)) print(parents)selectparent()
分频器
选择最适合的父母后,需要杂交才能产生后代。在这里,使用单点交叉。
def crossover(): 全局父母 cross_point = random.randint(0,5) 父母=父母+元组([(父母[0] [0:cross_point +1] +父母[1] [cross_point + 1:6])] ) parents = parents + tuple([(parents [1] [0:cross_point +1] + parents [0] [cross_point + 1:6])]) 打印(父母)
突变
交叉完成后,将进行突变以保持一代之间的多样性。在这里,我们将单点翻转位。
defmutation(): 全局种群,父母 静音= random.randint(0,49), 如果静音== 20: x = random.randint(0,3) y = random.randint(0,5) 父母[x] [ y] = 1个父母[x] [y] 人口=父母 印刷(人口)
我们需要多次重复整个过程,直到找到最佳解决方案为止。