差分进化算法(Differential Evolution,DE)由Storn和Price于1995年首次提出。主要用于求解实数优化问题。该算法是一类基于群体的自适应全局优化算法,属于演化算法的一种,由于其具有结构简单、容易实现、收敛快速、鲁棒性强等特点,因而被广泛应用在数据挖掘、模式识别、数字滤波器设计、人工神经网络、电磁学等各个领域。1996年在日本名古屋举行的第一届国际演化计算(ICEO)竞赛中,差分进化算法被证明是速度最快的进化算法。
和遗传算法一样,差分进化算法也是一种基于现代智能理论的优化算法,通过群体内个体之间的相互合作与竞争产生的群体智能来指导优化搜索的方向。该算法的基本思想是:从一个随机产生的初始种群开始,通过把种群中任意两个个体的向量差与第三个个体求和来产生新个体,然后将新个体与当代种群中相应的个体相比较,如果新个体的适应度优于当前个体的适应度,则在下一代中就用新个体取代旧个体,否则仍保存旧个体。通过不断地进化,保留优良个体,淘汰劣质个体,引导搜索向最优解逼近。
为了使更多研究者了解和研究差分进化算法,Storn和Price于1997年建立了差分进化算法的官方网站,该网站的建立得到了广大研究者的关注和支持,为相关人员进行差分演化算法的理论和应用研究提供了极大的方便。此外,Store和Price在差分进化算法上没有申请任何形式的专利,这也为推动差分进化算法的研究和应用起到了重要的作用。
差分进化算法的流程:
采用的适应度函数为:
变异操作的原理:
变异的本质是随机重原始种群中选择三个个体,并使用这三个个体按照图片中的式子新生成一个个体。需要注意的是:经过变异之后会生成一个新种群H,新种群中的每个个体都是由上述方式生成。
交叉操作原理:
下面图中的箭头横线上的内容为:rand(0,1)<=cr
交叉的本质是:将原始种群和变异生成的新种群进行比较,这里比较的是每个个体的每个染色体,
通过随机生成一个[0,1]之间的随机数,若这个随机数<=交叉概率cr,则选择变异之后该个体的相应染色体,否则选择原始种群中个体的染色体。交叉操作也会生成一个新的种群V。
选择操作原理:
选择操作是将原始种群与交叉操作生成的种群V做对比,谁的适应度值小,那么就选择谁作为新种群中的个体,选择操作也会生成一个新种群。
代码实现:
import math import random #参数设置 N=20 #种群个体数 dim=2 #种群维度 T=300 #种群迭代次数 F=0.5 #缩放因子 cr=0.5 #交叉概率 l=-4 #下限 r=4 #上限 #用于存放全局最优位置 Gbest=float('inf') Gbest_pos=[0 for i in range(dim)] # 初始化种群 def initial(): population=[] for i in range(N): chromosome=[]#每个个体的染色体 for j in range(dim): chromosome.append(random.uniform(l,r))#自变量的范围是[-4,4] population.append(chromosome) return population #计算适应度值 def fitness(x,y): fit=-20*math.exp(-0.2*math.sqrt(0.5*(x**2+y**2)))-math.exp(0.5*(math.cos(2*math.pi*x)++2*math.cos(2*math.pi*y)))+20+math.exp(1) return fit #变异操作 def mutate(population): #变异操作的结果是一个新的种群,所以先初始化一个值均为0的种群 H=[] #开始进行变异操作 for i in range(N): #每次随机循环选出三个不相同的个体 individual=random.sample(range(0,20),3) # print(individual) temp=[] #根据随机三个个体生成新的个体 for j in range(dim): temp.append(population[individual[0]][j]+F*(population[individual[1]][j]-population[individual[2]][j])) #将新生成的个体加入新种群中 H.append(temp) return H #交叉操作 def crossover(population,H): newpopulation = [] # 用来存放新的种群 # 遍历每一个个体中对应位置的染色体,若随机数大于cr 则选择H中个体染色体,否则选择原始种群中的 for i in range(N): temp=[]#用来存放新的个体 for j in range(dim): #随机生成一个0-1之间的小数 c=random.uniform(0,1) #如果c<=cr,则选择H中个体染色体 if(c<=cr): temp.append(H[i][j]) else: temp.append(population[i][j]) #将新产生的个个体加入新种群 newpopulation.append(temp) return newpopulation #选择操作 def selection(population,V): newpopulation=[] for i in range(N): temp=[] #计算population和V种群中个体的适应度值,谁低选谁 pfit=fitness(population[i][0],population[i][1]) vfit=fitness(V[i][0],V[i][1]) if vfit<pfit: temp=V[i].copy() else: temp=population[i].copy() newpopulation.append(temp) return newpopulation #主程序 population = initial() print("初始种群:",population) #迭代 while T>0: #变异操作 H=mutate(population) #交叉操作 V=crossover(population,H) #选择操作 newpopulation=selection(population,V) #选择最优 for i in range(N): fit=fitness(newpopulation[i][0],newpopulation[i][1]) #如果该位置小于全局最优 则更新全局最优的值和位置 if fit<Gbest: Gbest=fit Gbest_pos=newpopulation[i].copy() #赋值是为了后面还要继续对新产生的种群进行变异、交叉、选择 population=newpopulation T-=1 print("最终种群为:",population) #迭代完成,输出全局最优 print("全局最优值为:",Gbest) print("全局最优位置为:",Gbest_pos)
结果展示: