遗传算法简介及代码详解
jupyter 遗传算法代码

一、什么是Jupyter和遗传算法Jupyter是一种交互式计算环境,可以用于数据清洗和转换、数值模拟、统计建模、数据可视化和机器学习等多种数据处理工作。
而遗传算法是一种模拟自然选择和遗传规律的优化算法,主要用于解决复杂的优化问题。
二、Jupyter中的遗传算法实现在Jupyter中,可以使用Python编程语言来实现遗传算法。
首先需要引入相关的库,如numpy、random等,然后按照遗传算法的基本原理来编写代码。
三、遗传算法的基本原理1. 初始化种裙:随机生成一定数量的个体作为初始种裙。
2. 选择:根据个体的适应度值,利用适应度函数进行选择,选择适应度高的个体作为父母个体。
3. 交叉:通过交叉操作,将父母个体的基因进行组合,产生新的个体。
4. 变异:对新个体的基因进行变异操作,引入新的基因信息。
5. 重复选择、交叉和变异操作,直到满足终止条件。
6. 最终得到适应度较高的个体,即为所求的优化解。
四、使用Jupyter编写遗传算法代码的步骤1. 引入相关的库```pythonimport numpy as npimport random```2. 初始化种裙```pythondef init_population(pop_size, chromosome_length):population = np.random.randint(0, 2, (pop_size, chromosome_length))return population```3. 选择```pythondef select(population, fitness_value):index = np.random.choice(np.arange(len(population)),size=len(population), replace=True,p=fitness_value/fitness_value.sum())return population[index]```4. 交叉```pythondef crossover(parents, pc=0.6):children = np.empty(parents.shape)for i in range(0, len(parents), 2):if np.random.rand() < pc:crossover_point = np.random.randint(1, len(parents[i])) children[i] = np.concatenate((parents[i][:crossover_point], parents[i+1][crossover_point:]))children[i+1] =np.concatenate((parents[i+1][:crossover_point],parents[i][crossover_point:]))else:children[i] = parents[i]children[i+1] = parents[i+1]return children```5. 变异```pythondef mutate(children, pm=0.01):for i in range(len(children)):for j in range(len(children[i])):if np.random.rand() < pm:children[i][j] = 1 - children[i][j]return children```6. 遗传算法主程序```pythonpop_size = 100chromosome_length = 10max_gen = 100population = init_population(pop_size, chromosome_length)for gen in range(max_gen):fitness_value = calculate_fitness_value(population)parents = select(population, fitness_value)children = crossover(parents)new_population = mutate(children)population = new_population```五、总结通过Jupyter和Python编程语言,我们可以比较轻松地实现遗传算法,并用于解决各种优化问题。
遗传算法详解(含MATLAB代码)

遗传算法详解(含MATLAB代码)Python遗传算法框架使用实例(一)使用Geatpy实现句子匹配在前面几篇文章中,我们已经介绍了高性能Python遗传和进化算法框架——Geatpy的使用。
本篇就一个案例进行展开讲述:pip install geatpy更新至Geatpy2的方法:pip install --upgrade --user geatpy查看版本号,在Python中执行:import geatpyprint(geatpy.__version__)我们都听过“无限猴子定理”,说的是有无限只猴子用无限的时间会产生特定的文章。
在无限猴子定理中,我们“假定”猴子们是没有像人类那样“智能”的,而且“假定”猴子不会自我学习。
因此,这些猴子需要“无限的时间"。
而在遗传算法中,由于采用的是启发式的进化搜索,因此不需要”无限的时间“就可以完成类似的工作。
当然,需要产生的文章篇幅越长,那么就需要越久的时间才能完成。
下面以产生"T om is a little boy, isn't he? Yes he is, he is a good and smart child and he is always ready to help others, all in all we all like him very much."的句子为例,讲述如何利用Geatpy实现句子的搜索。
之前的文章中我们已经讲述过如何使用Geatpy的进化算法框架实现遗传算法编程。
这里就直接用框架。
把自定义问题类和执行脚本编写在下面的"main.py”文件中:# -*- coding: utf-8 -*-import numpy as npimport geatpy as eaclass MyProblem(ea.Problem): # 继承Problem父类def __init__(self):name = 'MyProblem' # 初始化name(函数名称,可以随意设置) # 定义需要匹配的句子strs = 'Tom is a little boy, isn't he? Yes he is, he is a good and smart child and he is always ready to help others, all in all we all like him very much.'self.words = []for c in strs:self.words.append(ord(c)) # 把字符串转成ASCII码M = 1 # 初始化M(目标维数)maxormins = [1] # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标)Dim = len(self.words) # 初始化Dim(决策变量维数)varTypes = [1] * Dim # 初始化varTypes(决策变量的类型,元素为0表示对应的变量是连续的;1表示是离散的)lb = [32] * Dim # 决策变量下界ub = [122] * Dim # 决策变量上界lbin = [1] * Dim # 决策变量下边界ubin = [1] * Dim # 决策变量上边界# 调用父类构造方法完成实例化ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin)def aimFunc(self, pop): # 目标函数Vars = pop.Phen # 得到决策变量矩阵diff = np.sum((Vars - self.words)**2, 1)pop.ObjV = np.array([diff]).T # 把求得的目标函数值赋值给种群pop的ObjV执行脚本if __name__ == "__main__":"""================================实例化问题对象============================="""problem = MyProblem() # 生成问题对象"""==================================种群设置================================"""Encoding = 'RI' # 编码方式NIND = 50 # 种群规模Field = ea.crtfld(Encoding, problem.varTypes, problem.ranges,problem.borders) # 创建区域描述器population = ea.Population(Encoding, Field, NIND) # 实例化种群对象(此时种群还没被初始化,仅仅是完成种群对象的实例化)"""================================算法参数设置=============================="""myAlgorithm = ea.soea_DE_rand_1_L_templet(problem, population) # 实例化一个算法模板对象myAlgorithm.MAXGEN = 2000 # 最大进化代数"""===========================调用算法模板进行种群进化========================="""[population, obj_trace, var_trace] = myAlgorithm.run() # 执行算法模板population.save() # 把最后一代种群的信息保存到文件中# 输出结果best_gen = np.argmin(obj_trace[:, 1]) # 记录最优种群是在哪一代best_ObjV = obj_trace[best_gen, 1]print('最优的目标函数值为:%s'%(best_ObjV))print('有效进化代数:%s'%(obj_trace.shape[0]))print('最优的一代是第 %s 代'%(best_gen + 1))print('评价次数:%s'%(myAlgorithm.evalsNum))print('时间已过 %s 秒'%(myAlgorithm.passTime))for num in var_trace[best_gen, :]:print(chr(int(num)), end = '')上述代码中首先定义了一个问题类MyProblem,然后调用Geatpy内置的soea_DE_rand_1_L_templet算法模板,它实现的是差分进化算法DE-rand-1-L,详见源码:运行结果如下:种群信息导出完毕。
遗传算法代码python

遗传算法代码python一、简介遗传算法是一种通过模拟自然选择和遗传学原理来寻找最优解的优化算法。
它广泛应用于各种领域,包括优化问题、搜索和机器学习等。
二、代码概述以下是一个简单的遗传算法的Python代码示例,用于解决简单的优化问题。
该算法使用一个简单的二进制编码方式,并使用适应度函数来评估每个个体的适应度。
三、代码实现```pythonimportnumpyasnp#遗传算法参数POPULATION_SIZE=100#种群规模CROSSOVER_RATE=0.8#交叉概率MUTATION_RATE=0.1#变异概率MAX_GENERATIONS=100#最大迭代次数#适应度函数deffitness(individual):#在这里定义适应度函数,评估每个个体的适应度#这里简单地返回个体值的平方,可以根据实际问题进行调整returnnp.sum(individual**2)#初始种群生成pop=np.random.randint(2,size=(POPULATION_SIZE,))#迭代过程forgenerationinrange(MAX_GENERATIONS):#评估种群中每个个体的适应度fitness_values=np.apply_along_axis(fitness,1,pop)#选择种群selected_idx=np.random.choice(np.arange(POPULATION_SIZE), size=POPULATION_SIZE,replace=True,p=fitness_values/fitness_va lues.sum())selected_pop=pop[selected_idx]#交叉操作ifCROSSOVER_RATE>np.random.rand():cross_points=np.random.rand(POPULATION_SIZE,2)<0.5#随机选择交叉点cross_pop=np.array([np.hstack((individual[cross_points[i, 0]:cross_points[i,1]]+individual[cross_points[i,1]:],other))f ori,otherinenumerate(selected_pop)]).T#合并个体并随机交叉得到新的个体cross_pop=cross_pop[cross_points]#将交叉后的个体重新排列成原始种群大小selected_pop=np.vstack((selected_pop,cross_pop))#将新个体加入种群中#变异操作ifMUTATION_RATE>np.random.rand():mutated_pop=selected_pop+np.random.randn(POPULATION_SIZE, 1)*np.sqrt(np.log(POPULATION_SIZE))*(selected_pop!=pop).astyp e(np.float)#根据变异概率对个体进行变异操作,得到新的个体种群mutated_pop=mutated_pop[mutated_pop!=0]#将二进制种群中值为0的个体去掉,因为这些个体是随机的二进制串,不是解的一部分,不应该参与变异操作selected_pop=mutated_pop[:POPULATION_SIZE]#将新种群中除最后一个以外的部分加入原始种群中(即新的种群被排除了适应度最差的个体)#选择当前最好的个体(用于更新最优解)best_idx=np.argmax(fitness_values)best_solution=selected_pop[best_idx]print(f"Generation{generation}:Bestsolution:{best_solutio n}")```四、使用示例假设要解决一个简单的优化问题:求一个一维函数的最小值。
遗 传 算 法 详 解 ( 含 M A T L A B 代 码 )

GATBX遗传算法工具箱函数及实例讲解基本原理:遗传算法是一种典型的启发式算法,属于非数值算法范畴。
它是模拟达尔文的自然选择学说和自然界的生物进化过程的一种计算模型。
它是采用简单的编码技术来表示各种复杂的结构,并通过对一组编码表示进行简单的遗传操作和优胜劣汰的自然选择来指导学习和确定搜索的方向。
遗传算法的操作对象是一群二进制串(称为染色体、个体),即种群,每一个染色体都对应问题的一个解。
从初始种群出发,采用基于适应度函数的选择策略在当前种群中选择个体,使用杂交和变异来产生下一代种群。
如此模仿生命的进化进行不断演化,直到满足期望的终止条件。
运算流程:Step 1:对遗传算法的运行参数进行赋值。
参数包括种群规模、变量个数、交叉概率、变异概率以及遗传运算的终止进化代数。
Step 2:建立区域描述器。
根据轨道交通与常规公交运营协调模型的求解变量的约束条件,设置变量的取值范围。
Step 3:在Step 2的变量取值范围内,随机产生初始群体,代入适应度函数计算其适应度值。
Step 4:执行比例选择算子进行选择操作。
Step 5:按交叉概率对交叉算子执行交叉操作。
Step 6:按变异概率执行离散变异操作。
Step 7:计算Step 6得到局部最优解中每个个体的适应值,并执行最优个体保存策略。
Step 8:判断是否满足遗传运算的终止进化代数,不满足则返回Step 4,满足则输出运算结果。
运用遗传算法工具箱:运用基于Matlab的遗传算法工具箱非常方便,遗传算法工具箱里包括了我们需要的各种函数库。
目前,基于Matlab的遗传算法工具箱也很多,比较流行的有英国设菲尔德大学开发的遗传算法工具箱GATBX、GAOT以及Math Works公司推出的GADS。
实际上,GADS就是大家所看到的Matlab中自带的工具箱。
我在网上看到有问为什么遗传算法函数不能调用的问题,其实,主要就是因为用的工具箱不同。
因为,有些人用的是GATBX带有的函数,但MATLAB自带的遗传算法工具箱是GADS,GADS当然没有GATBX里的函数,因此运行程序时会报错,当你用MATLAB来编写遗传算法代码时,要根据你所安装的工具箱来编写代码。
matlab遗传算法代码

matlab遗传算法代码
1 、算法概述
遗传算法(Genetic Algorithms,GA)是一种仿生学优化算法,它借用遗传学中物
竞天择的进化规则,模拟“自然选择”与“遗传进化”得出选择最优解的过程。
其基本原
理是对现有的种群中的各个个体,将其表示成某种形式的编码,然后根据自变量与约束条件,利用杂交、变异等操作,产生新一代解的种群,不断重复这一过程,最终求出收敛到
最优解的种群。
2、遗传算法的作用
遗传算法的主要作用在于优化多元函数,能够在大量的变量影响目标函数值的情况下
寻求最优解。
和其它现有的数值优化技术比较,如梯度下降法等,遗传算法更能适应“凸”和“非凸”都能解决,不受约束条件与搜索空间的影响较大,又叫做“智能搜索法”。
在
计算机视觉等计算机技术领域,经常用遗传算法来对一系列特征参数进行搜索和调节,成
功优化提高了系统的正确处理率。
3、matlab遗传算法的实现
Matlab的遗传算法应用是基于GA Toolbox工具箱,它提供了一个功能强大的、可扩
展的包装器,可用于构建遗传算法模型。
(1)编写最优化函数:
使用和设置最优化表达式或函数、变量;
(2)设置参数编码:
设置变量的编码,比如选择0-1二进制、0-10十进制;
(3)选择遗传算法的方法
选择遗传算法的方法,可以在多个选择中选择,比如变异、杂交等;
(4)设置运算参数:
设置每代的种群数、最大进化的世代数;
(5)运行遗传算法:
根据设定的参数运行遗传算法,算出收敛到最优解的种群;
(6)获得最优解:
获得收敛到最优解的条件下的最优解,得出最优解所在位置等参数,完成整个优化搜索。
遗传算法代码

遗传算法代码遗传算法是一种基于自然选择和遗传学原理的优化算法,用于解决许多复杂的优化问题,如机器学习、图像处理、组合优化等。
以下是一个简单的遗传算法代码示例:1. 初始化种群首先,我们需要创建一组初始个体,称为种群。
每个个体都是由一组基因表示的,这些基因可能是一些数字、布尔值或其他类型的值。
我们可以使用随机数生成器生成这些基因,并将它们组合成一个个体。
2. 适应度函数为了衡量每个个体的表现,我们需要编写一个适应度函数。
该函数将计算每个个体的适应度得分,该得分反映了该个体在解决优化问题方面的能力。
适应度函数将对每个个体进行评分,并将其分配到一个适应度等级。
3. 选择操作选择操作是基于每个个体的适应度得分来选择哪些个体将被选择并用于生成下一代种群。
较高适应度的个体将有更高的概率被选择,而较低适应度的个体将有更低的概率被选择。
这通常是通过轮盘赌选择方法实现的。
4. 交叉操作交叉操作是将两个个体的基因组合并以生成新的个体。
我们可以将两个随机个体中的某些基因进行交换,从而创建新的个体。
这样的交叉操作将增加种群的多样性,使其更有可能找到最优解。
5. 变异操作变异操作是用于引入种群中的随机性的操作。
在变异操作中,我们将随机选择一个个体,并随机更改其中的一个或多个基因。
这将引入新的、未经探索的基因组合,从而增加种群的多样性。
6. 迭代随着种群不断进化,每个个体的适应度得分也将不断提高。
我们将重复执行选择、交叉和变异操作,以生成新的个体,并淘汰旧的个体。
这个不断迭代的过程将继续,直到达到预设的迭代次数或找到最优解为止。
这是一个简单的遗传算法代码示例,它演示了如何使用遗传算法来解决优化问题。
在实际应用中,我们可以进一步对算法进行优化,以获得更好的结果。
遗传算法解释及代码(一看就懂)

遗传算法( GA , Genetic Algorithm ) ,也称进化算法。
遗传算法是受达尔文的进化论的启发,借鉴生物进化过程而提出的一种启发式搜索算法。
因此在介绍遗传算法前有必要简单的介绍生物进化知识。
一.进化论知识作为遗传算法生物背景的介绍,下面内容了解即可:种群(Population):生物的进化以群体的形式进行,这样的一个群体称为种群。
个体:组成种群的单个生物。
基因 ( Gene ) :一个遗传因子。
染色体 ( Chromosome ):包含一组的基因。
生存竞争,适者生存:对环境适应度高的、牛B的个体参与繁殖的机会比较多,后代就会越来越多。
适应度低的个体参与繁殖的机会比较少,后代就会越来越少。
遗传与变异:新个体会遗传父母双方各一部分的基因,同时有一定的概率发生基因变异。
简单说来就是:繁殖过程,会发生基因交叉( Crossover ) ,基因突变( Mutation ) ,适应度( Fitness )低的个体会被逐步淘汰,而适应度高的个体会越来越多。
那么经过N代的自然选择后,保存下来的个体都是适应度很高的,其中很可能包含史上产生的适应度最高的那个个体。
二.遗传算法思想借鉴生物进化论,遗传算法将要解决的问题模拟成一个生物进化的过程,通过复制、交叉、突变等操作产生下一代的解,并逐步淘汰掉适应度函数值低的解,增加适应度函数值高的解。
这样进化N代后就很有可能会进化出适应度函数值很高的个体。
举个例子,使用遗传算法解决“0-1背包问题”的思路:0-1背包的解可以编码为一串0-1字符串(0:不取,1:取);首先,随机产生M个0-1字符串,然后评价这些0-1字符串作为0-1背包问题的解的优劣;然后,随机选择一些字符串通过交叉、突变等操作产生下一代的M个字符串,而且较优的解被选中的概率要比较高。
这样经过G代的进化后就可能会产生出0-1背包问题的一个“近似最优解”。
编码:需要将问题的解编码成字符串的形式才能使用遗传算法。
遗传算法matlab程序代码

遗传算法matlab程序代码
遗传算法(GA)是一种用于求解优化问题的算法,其主要思想是模拟
生物进化过程中的“选择、交叉、变异”操作,通过模拟这些操作,来寻
找最优解。
Matlab自带了GA算法工具箱,可以直接调用来实现遗传算法。
以下是遗传算法Matlab程序代码示例:
1.初始化
首先定义GA需要优化的目标函数f,以及GA算法的相关参数,如种
群大小、迭代次数、交叉概率、变异概率等,如下所示:
options = gaoptimset('PopulationSize',10,...
'Generations',50,...
2.运行遗传算法
运行GA算法时,需要调用MATLAB自带的ga函数,将目标函数、问
题的维度、上下界、约束条件和算法相关参数作为输入参数。
其中,上下
界和约束条件用于限制空间,防止到无效解。
代码如下:
[某,fval,reason,output,population] = ga(f,2,[],[],[],[],[-10,-10],[10,10],[],options);
3.结果分析
最后,将结果可视化并输出,可以使用Matlab的plot函数绘制出目
标函数的值随迭代次数的变化,如下所示:
plot(output.generations,output.bestf)
某label('Generation')
ylabel('Best function value')
总之,Matlab提供了方便易用的GA算法工具箱,开发者只需要根据具体问题定义好目标函数和相关参数,就能够在短时间内快速实现遗传算法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
遗传算法简述及代码详解声明:本文内容整理自网络,认为原作者同意转载,如有冒犯请联系我。
遗传算法基本内容遗传算法为群体优化算法,也就是从多个初始解开始进行优化,每个解称为一个染色体,各染色体之间通过竞争、合作、单独变异,不断进化。
遗传学与遗传算法中的基础术语比较染色体:又可以叫做基因型个体(individuals)群体/种群(population):一定数量的个体组成,及一定数量的染色体组成,群体中个体的数量叫做群体大小。
初始群体:若干染色体的集合,即解的规模,如30,50等,认为是随机选取的数据集合。
适应度(fitness):各个个体对环境的适应程度优化时先要将实际问题转换到遗传空间,就是把实际问题的解用染色体表示,称为编码,反过程为解码/译码,因为优化后要进行评价(此时得到的解是否较之前解优越),所以要返回问题空间,故要进行解码。
SGA采用二进制编码,染色体就是二进制位串,每一位可称为一个基因;如果直接生成二进制初始种群,则不必有编码过程,但要求解码时将染色体解码到问题可行域内。
遗传算法的准备工作:1) 数据转换操作,包括表现型到基因型的转换和基因型到表现型的转换。
前者是把求解空间中的参数转化成遗传空间中的染色体或者个体(encoding),后者是它的逆操作(decoding)2) 确定适应度计算函数,可以将个体值经过该函数转换为该个体的适应度,该适应度的高低要能充分反映该个体对于解得优秀程度。
非常重要的过程。
遗传算法基本过程为:1) 编码,创建初始群体2) 群体中个体适应度计算3) 评估适应度4) 根据适应度选择个体5) 被选择个体进行交叉繁殖6) 在繁殖的过程中引入变异机制7) 繁殖出新的群体,回到第二步实例一:(建议先看实例二)求 []30,0∈x 范围内的()210-=x y 的最小值1) 编码算法选择为"将x 转化为2进制的串",串的长度为5位(串的长度根据解的精度设 定,串长度越长解得精度越高)。
(等位基因的值为0 or 1)。
2) 计算适应度的方法是:先将个体串进行解码,转化为int 型的x 值,然后使用()210-=x y 作为其适应度计算合适(由于是最小值,所以结果越小,适应度也越好)。
需要说明,将原目标函数设置为适应度函数是一种选择,但未必是最贴切的方法。
3) 正式开始,先设置群体大小为4,然后初始化群体 => (在[0,31]范围内随机选取4个整 数就可以编码)4) 计算适应度Fi(由于是求解最小值,可以选取一个大的基准线1000 ()2101000--=x Fi )5) 计算每个个体的选择概率,选择概率要能够反映个体的优秀程度。
这里用一个很简单的 方法来确定选择概率 )(/Fi TOTAL Fi p =6) 选择根据所有个体的选择概率进行淘汰选择。
这里使用的是一个赌轮的方式进行淘汰选择。
先按照每个个体的选择概率创建一个赌轮,然后选取4次,每次先产生一个0-1的随机小数,然后判断该随机数落在那个段内就选取相对应的个体。
这个过程中,选取概率p 高的个体将可能被多次选择,而概率低的就可能被淘汰。
下面是一个简单的赌轮的例子13% 35% 15% 37% ----------|----------------------------|------------------|---------------------------------| 个体1 个体2 个体3 ^0.67 个体4 随机数为0.67落在了个体4的端内,本次选择了个体4。
被选中的个体将进入配对库(mating pool ,配对群体)准备开始繁殖。
7) 简单交叉先对配对库中的个体进行随机配对,然后在配对的2个个体中设置交叉点,交换2个个体的信息后产生下一代。
比如( | 代表简单串的交叉位置)( 0110|1,1100|0 ) --交叉--> (01100,11001) ( 01|000,11|011 ) --交叉--> (01011,11000)2个父代的个体在交叉后繁殖出了下一代的同样数量的个体.复杂的交叉在交叉的位置,交叉的方法,双亲的数量上都可以选择.其目的都在于尽可能的培育出更优秀的后代 8) 变异变异操作时按照基因座来的,比如说每计算2万个基因座就发生一个变异(我们现在的每个个体有5个基因座。
也就是说要进化1000代后才会在其中的某个基因座发生一次变异)变异的结果是基因座上的等位基因发生了变化。
我们这里的例子就是把0变成1或则1变成0。
至此,我们已经产生了一个新的(下一代)群体,然后回到第4步,周而复始,生生不息下去。
实例二:为了便于理解,手工计算来简单地模拟遗传算法的各个主要执行步骤:(1)个体编码遗传算法的运算对象是表示个体的符号串,所以必须把变量 x1, x2 编码为一种符号串。
本题中,用无符号二进制整数(编码方式较多)来表示。
因 x1, x2 为 0 ~ 7之间的整数,所以分别用3位无符号二进制整数来表示,将它们连接在一起所组成的6位无符号二进制数就形成了个体的基因型,表示一个可行解。
例如,基因型 X =101110 所对应的表现型是:x =[ 5,6 ]。
个体的表现型x 和基因型X 之间可通过编码和解码程序相互转换。
(2) 初始群体的产生遗传算法是对群体进行的进化操作,需要给其淮备一些表示起始搜索点的初始群体数据。
本例中,群体规模的大小(随机选取)取为4,即群体由4个个体组成,每个个体可通过随机方法产生。
如:011101,101011,011100,111001(3) 适应度汁算遗传算法中以个体适应度的大小来评定各个个体的优劣程度,从而决定其遗传机会的大小。
本例中,目标函数总取非负值,并且是以求函数最大值为优化目标,故可直接利用目标函数值作为个体的适应度(适应度函数可以有许多)。
(4) 选择运算选择运算(或称为复制运算)把当前群体中适应度较高的个体按某种规则或模型遗传到下一代群体中。
一般要求适应度较高的个体将有更多的机会遗传到下一代群体中。
本例中,我们采用与适应度成正比的概率来确定各个个体复制到下一代群体中的数量。
其具体操作过程是:• 先计算出群体中所有个体的适应度的总和 ∑===Mi M i fiFI 1),,1(Λ;• 其次计算出每个个体的相对适应度的大小),,1(/M i FIfi Λ=,它即为每个个体被遗传到下一代群体中的概率;• 每个概率值组成一个区域,全部概率值之和为1;• 最后再产生一个0到1之间的随机数,依据该随机数出现在上述哪一个概率 区域内来确定各个个体被选中的次数。
(详见下图)(5)交叉运算交叉运算是遗传算法中产生新个体的主要操作过程,它以某一概率相互交换某两个个体之间的部分染色体。
本例采用单点交叉的方法,其具体操作过程是:•先对群体进行随机配对;•其次随机设置交叉点位置;•最后再相互交换配对染色体之间的部分基因。
(6) 变异运算变异运算是对个体的某一个或某一些基因座上的基因值按某一较小的概率进行改变,它也是产生新个体的一种操作方法。
本例中,我们采用基本位变异的方法来进行变异运算,其具体操作过程是:•首先确定出各个个体的基因变异位置,下表所示为随机产生的变异点位置,其中的数字表示变异点设置在该基因座处;•然后依照某一概率将变异点的原有基因值取反。
对群体P(t)进行一轮选择、交叉、变异运算之后可得到新一代的群体p(t+1)。
从上表中可以看出,群体经过一代进化之后,其适应度的最大值、平均值都得到了明显的改进。
事实上,这里已经找到了最佳个体“111111”。
[注意]需要说明的是,表中有些栏的数据是随机产生的。
这里为了更好地说明问题,我们特意选择了一些较好的数值以便能够得到较好的结果,而在实际运算过程中,有可能需要一定的循环次数才能达到这个最优结果。
选择要能够合理的反映“适者生存”的自然法则,而交叉必须将有利的基因尽量遗传给下一代(这是算法的关键!)算法过程当中有几个随机过程:(1)初始种群的产生是随机产生,但有时为了更好迭代,知道解在某一个值附近,可以认为设定初始种群(2)确定个体被选中次数时,运用到轮赌法,其产生的数据为随机数据(3)交叉点(4)变异点伪代码://Init populationforeach individual in population{individual = Encode(Random(0,31));}while (App.IsRun){//计算个体适应度int TotalF = 0;foreach individual in population{individual.F = 1000 - (Decode(individual)-10)^2;TotalF += individual.F;}//------选择过程,计算个体选择概率-----------foreach individual in population{individual.P = individual.F / TotalF;}//选择for(int i=0;i<4;i++){//SelectIndividual(float p)是根据随机数落在段落计算选取哪个个体的函数MatingPool[i] = population[SelectIndividual(Random(0,1))];}//-------简单交叉---------------------------//由于只有4个个体,配对2次for(int i=0;i<2;i++){MatingPool.Parents[i].Mother = MatingPool.RandomPop();MatingPool.Parents[i].Father = MatingPool.RandomPop();}//交叉后创建新的集团population.Clean();foreach Parent in MatingPool.Parents{//注意在copy 双亲的染色体时在某个基因座上发生的变异未表现.child1 = Parent.Mother.DivHeader + Parent.Father.DivEnd;child2 = Parent.Father.DivHeader + Parent.Mother.DivEnd;population.push(child1);population.push(child2);}}完整代码如下:#include"stdafx.h"#include<stdio.h>#include<stdlib.h>#include<time.h>#define POPSIZE 500#define MAXIMIZATION 1 //求解函数为求最大值#define MINIMIZATION 2 //求解函数为求最小值#define Cmax 100 //求解最大值时适应度函数的基准数#define Cmin 0 //求解最小值时适应度函数的基准数#define LENGTH110 //每一个解用位基因表示#define LENGTH210#define CHROMLENGTH LENGTH1+LENGTH2int FunctionMode=MAXIMIZATION; //函数值求解类型是最大值int PopSize=80; //种群规模int MaxGeneration =100; //最大世代数,即最大迭代数double Pc = 0.6; //变异概率double Pm = 0.001; //交叉概率struct individual//定义个体{char chrom[CHROMLENGTH+1]; //个体数double value; //个体对应的变量值double fitness; //个体适应度};int generation;int best_index;int worst_index;struct individual bestindividual;struct individual worstindividual;struct individual currentbest;struct individual population[POPSIZE];void GenerateInitialPopulation(void); / /初始种群生成void GenerateNextPopulation(void); //产生下一代种群void EvaluatePopulation(void);void CalculateObjectValue(void);long DecodeChromosome(char *,int,int); //译码void CalculateFitnessValue(void);void FindBestAndWorstIndividual(void);void PerformEvolution(void);void SelectionOperator(void);void CrossoverOperator(void);void MutationOperator(void);void OutputTextReport(void);void main(void){generation=0;GenerateInitialPopulation(); //初始种群生成EvaluatePopulation(); //计算种群值,即计算种群适应度while(generation<MaxGeneration){generation++;GenerateNextPopulation(); //产生下一代种群EvaluatePopulation(); //计算种群值,即计算种群适应度PerformEvolution();OutputTextReport();}}void GenerateInitialPopulation(void) //随机产生初始种群,且用0,1表示{int i,j;for(i=0;i<PopSize; i++){for(j=0;j<CHROMLENGTH;j++){population[i].chrom[j]=(rand()%10<5)?'0':'1'; //rand()%n产生一个// ~n-1的数}population[i].chrom[CHROMLENGTH]='\0';}}void GenerateNextPopulation(void){SelectionOperator();CrossoverOperator();MutationOperator();}void EvaluatePopulation(){CalculateObjectValue();CalculateFitnessValue (); FindBestAndWorstIndividual (); }long DecodeChromosome (char *string ,int point ,int length ) //译码,换算为十进 //制数 { int i ;long decimal =0L; char *pointer ;for (i =0,pointer =string +point ;i <length ;i ++,pointer ++) {decimal +=(*pointer -'0')<<(length -1-i ); //移位操作,染色体实现十进//制化 }return (decimal ); }void CalculateObjectValue (void ) //计算函数值 {int i ;long temp1,temp2; double x1,x2;for (i =0;i <PopSize ;i ++){ //从染色体中读取基因temp1=DecodeChromosome (population [i ].chrom ,0,LENGTH1);temp2=DecodeChromosome (population [i ].chrom ,LENGTH1,LENGTH2);x1=4.0 *temp1/1023.0-2.0 ; //x ∈[a, b];x2=4.0 *temp2/1023.0-2.0 ; // 121*)(10--+=temp a b a xpopulation [i ].value =100*(x1*x2+x2)*(x1*x2-x2)*x2;// 函数表达式} }void CalculateFitnessValue (void ) //针对不同函数类型计算个体适应度 {int i ;double temp;for (i=0;i<PopSize;i++){if (FunctionMode==MAXIMIZATION) //函数类型为求解最大值{if((population[i].value+Cmin)>0.0){temp=Cmin+population[i].value;}else{temp=0.0;}}else if(FunctionMode==MINIMIZATION) //函数类型为求解最小值{if(population[i].value<Cmax){temp=Cmax-population[i].value;}else{temp=0.0;}}population[i].fitness=temp;}}void FindBestAndWorstIndividual(void ){int i;double sum=0.0;bestindividual=population[0];worstindividual=population[0];for (i=1;i<PopSize; i++){if (population[i].fitness>bestindividual.fitness){bestindividual=population[i];best_index=i;}else if (population[i].fitness<worstindividual.fitness){worstindividual=population[i];worst_index=i;}sum+=population[i].fitness;}if (generation==0){currentbest=bestindividual;}else{if(bestindividual.fitness>=currentbest.fitness){currentbest=bestindividual;}}}void PerformEvolution(void) //执行进化{if (bestindividual.fitness>currentbest.fitness){currentbest=population[best_index];}else{population[worst_index]=currentbest;}}void SelectionOperator(void) //选取最优进化代{int i,index;double p,sum=0.0;double cfitness[POPSIZE];struct individual newpopulation[POPSIZE];for(i=0;i<PopSize;i++){sum+=population[i].fitness;}for(i=0;i<PopSize; i++)cfitness[i]=population[i].fitness/sum; // 个体的适应度比例}for(i=1;i<PopSize; i++){cfitness[i]=cfitness[i-1]+cfitness[i];}for (i=0;i<PopSize;i++){p=rand()%1000/1000.0;index=0;while (p>cfitness[index]){index++;}newpopulation[i]=population[index];}for(i=0;i<PopSize; i++){population[i]=newpopulation[i];}}void CrossoverOperator(void) //染色体交叉{int i,j;int index[POPSIZE];int point,temp;double p;char ch;for (i=0;i<PopSize;i++){index[i]=i;}for(i=0;i<PopSize;i++) //随机化种群内染色体{point=rand()%(PopSize-i);temp=index[i];index[i]=index[point+i];index[point+i]=temp;}for (i=0;i<PopSize-1;i+=2)p=rand()%1000/1000.0; //随机产生交叉概率if (p<Pc){point=rand()%(CHROMLENGTH-1)+1;for (j=point; j<CHROMLENGTH;j++) //交叉{ch=population[index[i]].chrom[j];population[index[i]].chrom[j]=population[index[i+1]].chrom[j];population[index[i+1]].chrom[j]=ch;}}}}void MutationOperator(void) //基因变异{int i,j;double p;for(i=0;i<PopSize;i++){for(j=0;j<CHROMLENGTH;j++){p=rand()%1001/1000.0;if (p<Pm){population[i].chrom[j]=(population[i].chrom[j]==0)?'1':'0';}}}}void OutputTextReport(void) //列印结果{int i;double sum;double average;sum=0.0;for(i=0;i<PopSize;i++){sum+=population[i].value;}average=sum/PopSize;printf("gen=%d,avg=%f,best=%f,",generation,average,currentbest.value);printf("chromosome=");for (i=0;i<CHROMLENGTH;i++){printf("%c",currentbest.chrom[i]);}Long temp1=DecodeChromosome(population[i].chrom,0,LENGTH1);//从染色体中读取基因longtemp2=DecodeChromosome(population[i].chrom,LENGTH1,LENGTH2);double x1=4.0*temp1/1023.0-2.0;//基因型换为表现型double x2=4.0*temp2/1023.0-2.0;printf(" x1=%f,x2=%f",x1,x2);printf("\n");}。