基本信息
源码名称:python遗传算法(入门级示例)
源码大小:8.32KB
文件格式:.py
开发语言:Python
更新时间:2019-04-30
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
遗传算法
遗传算法
import numpy as np from scipy.optimize import fsolve, basinhopping import random import timeit # 根据解的精度确定染色体(chromosome)的长度 # 需要根据决策变量的上下边界来确定 def getEncodedLength(delta=0.0001, boundarylist=[]): # 每个变量的编码长度 lengths = [] for i in boundarylist: lower = i[0] upper = i[1] # lamnda 代表匿名函数f(x)=0,50代表搜索的初始解 res = fsolve(lambda x: ((upper - lower) * 1 / delta) - 2 ** x - 1, 50) length = int(np.floor(res[0])) lengths.append(length) return lengths pass # 随机生成初始编码种群 def getIntialPopulation(encodelength, populationSize): # 随机化初始种群为0 chromosomes = np.zeros((populationSize, sum(encodelength)), dtype=np.uint8) for i in range(populationSize): chromosomes[i, :] = np.random.randint(0, 2, sum(encodelength)) # print('chromosomes shape:', chromosomes.shape) return chromosomes # 染色体解码得到表现型的解 def decodedChromosome(encodelength, chromosomes, boundarylist, delta=0.0001): populations = chromosomes.shape[0] variables = len(encodelength) decodedvalues = np.zeros((populations, variables)) for k, chromosome in enumerate(chromosomes): chromosome = chromosome.tolist() start = 0 for index, length in enumerate(encodelength): # 将一个染色体进行拆分,得到染色体片段 power = length - 1 # 解码得到的10进制数字 demical = 0 for i in range(start, length start): demical = chromosome[i] * (2 ** power) power -= 1 lower = boundarylist[index][0] upper = boundarylist[index][1] decodedvalue = lower demical * (upper - lower) / (2 ** length - 1) decodedvalues[k, index] = decodedvalue # 开始去下一段染色体的编码 start = length return decodedvalues # 得到个体的适应度值及每个个体被选择的累积概率 def getFitnessValue(func, chromosomesdecoded): # 得到种群规模和决策变量的个数 population, nums = chromosomesdecoded.shape # 初始化种群的适应度值为0 fitnessvalues = np.zeros((population, 1)) # 计算适应度值 for i in range(population): fitnessvalues[i, 0] = func(chromosomesdecoded[i, :]) # 计算每个染色体被选择的概率 probability = fitnessvalues / np.sum(fitnessvalues) # 得到每个染色体被选中的累积概率 cum_probability = np.cumsum(probability) return fitnessvalues, cum_probability # 新种群选择 def selectNewPopulation(chromosomes, cum_probability): m, n = chromosomes.shape newpopulation = np.zeros((m, n), dtype=np.uint8) # 随机产生M个概率值 randoms = np.random.rand(m) for i, randoma in enumerate(randoms): logical = cum_probability >= randoma index = np.where(logical == 1) # index是tuple,tuple中元素是ndarray newpopulation[i, :] = chromosomes[index[0][0], :] return newpopulation pass # 新种群交叉 def crossover(population, Pc=0.8): """ :param population: 新种群 :param Pc: 交叉概率默认是0.8 :return: 交叉后得到的新种群 """ # 根据交叉概率计算需要进行交叉的个体个数 m, n = population.shape numbers = np.uint8(m * Pc) # 确保进行交叉的染色体个数是偶数个 if numbers % 2 != 0: numbers = 1 # 交叉后得到的新种群 updatepopulation = np.zeros((m, n), dtype=np.uint8) # 产生随机索引 index = random.sample(range(m), numbers) # 不进行交叉的染色体进行复制 for i in range(m): if not index.__contains__(i): updatepopulation[i, :] = population[i, :] # crossover while len(index) > 0: a = index.pop() b = index.pop() # 随机产生一个交叉点 crossoverPoint = random.sample(range(1, n), 1) crossoverPoint = crossoverPoint[0] # one-single-point crossover updatepopulation[a, 0:crossoverPoint] = population[a, 0:crossoverPoint] updatepopulation[a, crossoverPoint:] = population[b, crossoverPoint:] updatepopulation[b, 0:crossoverPoint] = population[b, 0:crossoverPoint] updatepopulation[b, crossoverPoint:] = population[a, crossoverPoint:] return updatepopulation pass # 染色体变异 def mutation(population, Pm=0.01): """ :param population: 经交叉后得到的种群 :param Pm: 变异概率默认是0.01 :return: 经变异操作后的新种群 """ updatepopulation = np.copy(population) m, n = population.shape # 计算需要变异的基因个数 gene_num = np.uint8(m * n * Pm) # 将所有的基因按照序号进行10进制编码,则共有m*n个基因 # 随机抽取gene_num个基因进行基本位变异 mutationGeneIndex = random.sample(range(0, m * n), gene_num) # 确定每个将要变异的基因在整个染色体中的基因座(即基因的具体位置) for gene in mutationGeneIndex: # 确定变异基因位于第几个染色体 chromosomeIndex = gene // n # 确定变异基因位于当前染色体的第几个基因位 geneIndex = gene % n # mutation if updatepopulation[chromosomeIndex, geneIndex] == 0: updatepopulation[chromosomeIndex, geneIndex] = 1 else: updatepopulation[chromosomeIndex, geneIndex] = 0 return updatepopulation pass # 定义适应度函数 目标函数 # maxf(x1,x2) = 21.5 x1*sin(4*pi*x1) x2*sin(20*pi*x2) # s.t. -3.0<=x1<=12.1 4.1<=x2<=5.8 def fitnessFunction(): return lambda x: 21.5 x[0] * np.sin(4 * np.pi * x[0]) x[1] * np.sin(20 * np.pi * x[1]) pass def main(max_iter=500): # 每次迭代得到的最优解 optimalSolutions = [] optimalValues = [] # 决策变量的取值范围 decisionVariables = [[-3.0, 12.1], [4.1, 5.8]] # 得到染色体编码长度 lengthEncode = getEncodedLength(boundarylist=decisionVariables) for iteration in range(max_iter): # 得到初始种群编码 chromosomesEncoded = getIntialPopulation(lengthEncode, 10) # 种群解码 decoded = decodedChromosome(lengthEncode, chromosomesEncoded, decisionVariables) # 得到个体适应度值和个体的累积概率 evalvalues, cum_proba = getFitnessValue(fitnessFunction(), decoded) # 选择新的种群 newpopulations = selectNewPopulation(chromosomesEncoded, cum_proba) # 进行交叉操作 crossoverpopulation = crossover(newpopulations) # mutation mutationpopulation = mutation(crossoverpopulation) # 将变异后的种群解码,得到每轮迭代最终的种群 final_decoded = decodedChromosome(lengthEncode, mutationpopulation, decisionVariables) # 适应度评价 fitnessvalues, cum_individual_proba = getFitnessValue(fitnessFunction(), final_decoded) # 搜索每次迭代的最优解,以及最优解对应的目标函数的取值 optimalValues.append(np.max(list(fitnessvalues))) index = np.where(fitnessvalues == max(list(fitnessvalues))) optimalSolutions.append(final_decoded[index[0][0], :]) # 搜索最优解 optimalValue = np.max(optimalValues) optimalIndex = np.where(optimalValues == optimalValue) optimalSolution = optimalSolutions[optimalIndex[0][0]] return optimalSolution, optimalValue solution, value = main() print('最优解: x1, x2') print(solution[0], solution[1]) print('最优目标函数值:', value) # 测量运行时间 elapsedtime = timeit.timeit(stmt=main, number=1) print('Searching Time Elapsed:(S)', elapsedtime)