遗传算法解简单的函数极值问题
作者:邬杨明
1 import numpy 2 import matplotlib.pyplot as plt 3 import random 4 import operator 5 6 x_label=[] 7 y_label=[]#将每一步迭代的结果存储到列表中,便于画图 8 class GA(object): 9 def __init__(self,length,number,lower_boundary,upper_boundary,iter_number): 10 self.length = length#确定染色体编码长度 11 self.number = number#确定初始化种群数量 12 self.lower_boundary = lower_boundary#定义域下界 13 self.upper_boundary = upper_boundary#定义域上届 14 self.population = self.initial_population(length,number) 15 self.iteration(iter_number) 16 def initial_population(self,length,number):#初始化种群 17 return [self.initial_chromosome(length) for i in range(number)] 18 def initial_chromosome(self,length):#编码 19 """ 20 随机生成长度为length的染色体,每个基因的取值是0或1 21 这里用一个bit表示一个基因 22 """ 23 chromosome = 0 24 for i in range(self.length): 25 chromosome |= (1 << i) * random.randint(0, 1) 26 # print(chromosome) 27 # print(num) 28 return chromosome 29 def decode(self,chromosome):#解码 30 x = chromosome*(self.upper_boundary-self.lower_boundary)/(2**self.length-1) 31 return x 32 def fitness_function(self,chromosome):#适应度函数 33 x = self.decode(chromosome) 34 y = x + 10 * numpy.sin(5 * x) + 7 * numpy.cos(4 * x) 35 return y 36 def evolution(self, retain_rate=0.2, random_select_rate=0.5, mutation_rate=0.01): 37 """ 38 对当前种群依次进行选择、交叉并生成新一代种群,然后对新一代种群进行变异 39 """ 40 parents = self.selection(retain_rate, random_select_rate) 41 self.crossover(parents) 42 self.mutation(mutation_rate) 43 def selection(self,retain_rate, random_select_rate): 44 graded = [(self.fitness_function(chromosome), chromosome) for chromosome in self.population] 45 sort = [x[1] for x in sorted(graded, reverse=True)] 46 retain_length=int(len(sort)*retain_rate) 47 #选出适应性强的个体,精英选择 48 parents=sort[:retain_length] 49 for chromosome in sort[retain_length:]: 50 if random.random() < random_select_rate: 51 parents.append(chromosome) 52 return parents 53 def crossover(self,parents):#交叉 54 children=[] 55 #需要繁殖的子代数量 56 target_number=len(self.population)-len(parents) 57 #开始繁殖 58 while len(children) < target_number: 59 father = random.randint(0, len(parents) - 1) 60 mother = random.randint(0, len(parents) - 1) 61 if father != mother: 62 # 随机选取交叉点 63 cross_point = random.randint(0, self.length) 64 # 生成掩码,方便位操作 65 mark = 0 66 for i in range(cross_point): 67 mark |= (1 << i) 68 father = parents[father] 69 mother = parents[mother] 70 # 孩子将获得父亲在交叉点前的基因和母亲在交叉点后(包括交叉点)的基因 71 child = ((father & mark) | (mother & ~mark)) & ((1 << self.length) - 1) 72 children.append(child) 73 # 经过繁殖后,孩子和父母的数量与原始种群数量相等,在这里可以更新种群。 74 self.population = parents + children 75 def mutation(self,rate): 76 for i in range(len(self.population)): 77 if random.random() < rate: 78 j = random.randint(0, self.length - 1)#s随机产生变异位置 79 self.population[i] ^= 1 << j #产生变异 80 def result(self): 81 ''' 82 获得近优值 83 ''' 84 graded = [(self.fitness_function(chromosome), chromosome) for chromosome in self.population] 85 graded = [x[1] for x in sorted(graded, reverse=True)] 86 # print('近优的x值为:', self.decode(graded[0]), 87 # '近优的y值为:', self.fitness_function(graded[0])) 88 #将每一步迭代的结果存储到列表中 89 y_label.append(self.fitness_function(graded[0])) 90 return self.decode(graded[0]) 91 def iteration(self,iter_number): 92 for i in range(iter_number): 93 self.evolution() 94 self.result() 95 x_label.append(i) 96 g1=GA(17,300,0,9,30)#建立一个实例 97 98 plt.plot(x_label,y_label) 99 plt.show() 100 g1.result()