GA示例代码
源自《深度学习计算机视觉实战 卷积神经网络、Python 、TensorFlow和Kivy》
作者:[埃] 艾哈迈德·法齐·迦得(Ahmed Fawzy Gad)著 林赐 译
优化具有六个参数的线性方程完整代码
import GA
import numpy as np
# 求解能使y = w1x1+w2x2+w3x3+w4y4+w5y5+w6y6最大的权值
# (x1,x2,x3,x4,x5,x6)=(4,-2,3.5,5,-11,-4.7)
# 方程的输入
equation_inputs = [4, -2, 3.5, 5, -11, -4.7]
# 待优化的权重数量
num_weights = 6
# GA参数:交配池大小、种群大小
sol_per_pop = 8
num_parents_mating = 4
# 定义种群大小
# 种群会有sol_per_pop条染色体,每个染色体上会有num_weights条基因
pop_size = (sol_per_pop, num_weights)
# 创建初始种群
new_population = np.random.uniform(low=-4.0, high=4.0, size=pop_size)
print(new_population)
num_generations = 10000
for generation in range(num_generations):
print("Generation : ", generation)
# 计算种群中每条染色体的适应度
fitness = GA.cal_pop_fitness(equation_inputs, new_population)
# 选择最适合交配的亲本
parents = GA.select_mating_pool(new_population, fitness, num_parents_mating)
# 用交叉实现下一代
offspring_crossover = GA.crossover(parents, offspring_size=(pop_size[0] - parents.shape[0], num_weights))
# 用突变增加后代的多样性
offspring_mutation = GA.mutation(offspring_crossover)
# 创建基于亲本和后代的新种群
new_population[0:parents.shape[0], :] = parents
new_population[parents.shape[0]:, :] = offspring_mutation
# 在此次迭代中的最佳结果
print("Best result : ", np.max(np.sum(new_population * equation_inputs, axis=1)))
# 迭代完成所有代后得到最佳解
# 起初,在最后一代中计算每个解的适应度
fitness = GA.cal_pop_fitness(equation_inputs, new_population)
# 然后返回最佳解的索引
best_match_idx = np.where(fitness == np.max(fitness))
print("Best Solution : ", new_population[best_match_idx, :])
print("Best Solution fitness :", fitness[best_match_idx])
GA模块
import numpy as np
# GA适应度函数
def cal_pop_fitness(equation_inputs, pop):
# 计算当前种群中每个解的适应度值
# 适应度函数计算每个输入与其相应权重之间的SOP
fitness = np.sum(pop * equation_inputs, axis=1)
return fitness
# 根据适应度值选择最佳亲本
def select_mating_pool(pop, fitness, num_parents):
inf = float("-inf")
# 选出本代最优秀的个体为亲本,生产下一代的后代
parents = np.empty((num_parents, pop.shape[1]))
for parents_num in range(num_parents):
max_fitness_idx = np.where(fitness == np.max(fitness))
max_fitness_idx = max_fitness_idx[0][0]
parents[parents_num, :] = pop[max_fitness_idx, :]
fitness[max_fitness_idx] = inf
return parents
# 交叉
def crossover(parents, offspring_size):
offspring = np.empty(offspring_size)
# 在双亲之间发生交叉的点,通常是在中心
crossover_point = np.uint8(offspring_size[1] / 2)
for k in range(offspring_size[0]):
# 第一个要交配的亲本的索引
parent1_idx = k % parents.shape[0]
# 第二个要交配的亲本的索引
parent2_idx = (k + 1) % parents.shape[0]
# 新的后代的前一半基因将取自第一个父母
offspring[k, 0:crossover_point] = parents[parent1_idx, 0:crossover_point]
# 新的后代的后一半基因将取自第二个父母
offspring[k, crossover_point:] = parents[parent2_idx, crossover_point:]
return offspring
# 突变
def mutation(offspring_crossover):
# 随机改变子代中的一个基因
for idx in range(offspring_crossover.shape[0]):
# 基因加上一个随机值
random_value = np.random.uniform(low=-1.0, high=1.0, size=1)
offspring_crossover[idx, 4] += random_value
return offspring_crossover