1.整体流程(有不懂的地方可以在评论区留言)
初始化种群,计算适应性,选择,交叉,变异,更新并评估,判断是否达到最大迭代次数,输出最佳目标函数
2.求9*sin(5*x)+8*cos(4*x)最优值(matlab)
clear all; popsize=20; %群体大小 chromlength=10; %字符串长度(个体长度) pc=0.7; %交叉概率 pm=0.005; %变异概率 pop=initpop(popsize,chromlength); %随机产生初始群体 for i=1:20 %20为迭代次数 value=calobjvalue(pop); %计算目标函数 fitvalue=calfitvalue(value); %计算群体中每个个体的适应度 newpop=selection(pop,fitvalue); %复制 newpop=crossover(pop,pc); %交叉 newpop=mutation(pop,pc); %变异 [bestindividual,bestfit]=best(pop,fitvalue);%求出群体中适应值最大的个体及其适应值 y(i)=max(bestfit); n(i)=i; pop3=bestindividual; x(i)=decodechrom(pop3,1,chromlength)*10/1023; pop=newpop; end fplot('9*sin(5*x)+8*cos(4*x)'); hold on; plot(x,y,'r+'); hold off;
3.求y=sin(10*x)*x + cos(2*x)*x 在【0, 5】区间最大值(Python)
import numpy as np DNA_SIZE = 10 # DNA length POP_SIZE = 100 # population size CROSS_RATE = 0.8 # mating probability (DNA crossover) MUTATION_RATE = 0.003 # mutation probability N_GENERATIONS = 200 X_BOUND = [0, 5] # x upper and lower bounds def F(x): return np.sin(10*x)*x + np.cos(2*x)*x # to find the maximum of this function def get_fitness(pred): return pred - np.min(pred) + 1e-3 # 防止出现非正值,因为 select 时概率非负。 def translateDNA(pop): # np.arange(DNA_SIZE)[::-1] --> array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) # 2 ** np.arange(DNA_SIZE)[::-1] --> array([512, 256, 128, 64, 32, 16, 8, 4, 2, 1], dtype=int32) # pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) --> 将二进制转换为十进制 # (2 ** DNA_SIZE - 1) --> 1023 # pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / (2 ** DNA_SIZE - 1) --> 计算染色体值占最大值(1023)的比例 # pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / (2 ** DNA_SIZE - 1) * X_BOUND[1] --> 将范围从[0, 1023]缩放到[0, 5] return pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / (2 ** DNA_SIZE - 1) * X_BOUND[1] def select(pop, fitness): # 在 np.arange(POP_SIZE) 中依概率 p 选出 size 个染色体代号 # replace=True 表示选出的染色体可以有重复的 idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True, p=fitness / fitness.sum()) return pop[idx] def crossover(parent, pop): if np.random.rand() < CROSS_RATE: i_ = np.random.randint(0, POP_SIZE, size=1) # 选定 pop 中需要交叉的染色体,如 i_ = 1,表示第二条染色体 # 选择需要改变的基因,如 cross_points = [False True True False False True False True True False] # 表示第2,3,6,8,9个位置上的基因会改变 cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(np.bool) # pop[i_, cross_points] 会得到 pop 种群中 i_ 这条染色体上的 cross_points 中 True 位置上的基因 # parent[cross_points] = pop[i_, cross_points] 将刚刚得到的基因放到 parent 这条染色体的 cross_points 中 True 的位置上 parent[cross_points] = pop[i_, cross_points] return parent def mutate(child): for point in range(DNA_SIZE): if np.random.rand() < MUTATION_RATE: child[point] = 1 if child[point] == 0 else 0 return child pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE)) # initialize the pop DNA print(pop.shape) for _ in range(N_GENERATIONS): F_values = F(translateDNA(pop)) # compute function value by extracting DNA # GA part (evolution) fitness = get_fitness(F_values) print("Most fitted DNA: ", pop[np.argmax(fitness), :], "适应度为:", round(fitness[np.argmax(fitness)], 3)) pop = select(pop, fitness) pop_copy = pop.copy() for parent in pop: child = crossover(parent, pop_copy) child = mutate(child) parent = child # 用经过交叉变异的下一代(新的染色体)来代替上一代(pop 种群中选出的) print('最大值为:', F(translateDNA(pop[np.argmax(fitness), :])))