赞
踩
遗传算法(Genetic Algorithm, GA)是模拟自然界中生物进化的机制来搜索最优解的方法。遗传算法属于进化计算的一部分,它借鉴了达尔文的自然选择和孟德尔的遗传学原理。
遗传算法的灵感来源于生物进化过程。在自然界中,生物通过基因的遗传和变异,以及环境的自然选择,逐步演化出适应环境的特征。遗传算法模拟这一过程,通过编码表示问题解的“染色体”,并利用选择、交叉(重组)、变异等操作来模拟生物进化过程,从而搜索问题的最优解。
遗传算法通常包含以下几个基本步骤:
遗传算法具有以下优势:
遗传算法广泛应用于各种优化和搜索问题,如工程优化、机器学习、经济调度、自动控制等领域。
遗传算法作为一种有效的全局搜索算法,通过模拟生物进化过程,能够在复杂问题中找到满意的解。它以其独特的搜索机制和优点,在多个领域得到了广泛的应用。然而,遗传算法也有其局限性,如算法参数的选择、计算量较大等问题,需要在实际应用中加以考虑和优化。
我们哪一个非常简单的优化为例讲一下:
目标函数:
y
=
x
2
y = x^2
y=x2
我们在一组数据中找到可以使得目标函数达到最大的值,x的取值范围是[0,31]
种群(Population)
:
遗传算法保持大量的个体(individuals)——针对当前问题的候选解集合。由于每个个体都由染色体表示,因此这些种族的个体(individuals)可以看作是染色体集合。比如我们在这里x的取值范围是[0,31],我们随机取5个数字[2,5,11,24,7]作为一个种群
,其中每一个数字就是个体;
基因(Genotype)
:
在自然界中,通过基因型表征繁殖,繁殖和突变,基因型是组成染色体的一组基因的集合。在遗传算法中,每个个体都由代表基因集合的染色体构成。例如,一条染色体可以表示为二进制串,其中每个位代表一个基因。比如我们上面随机取5个数字[2,5,11,24,7]作为一个种群
,每一个数字就是一个个体
,每个数字用二进制表示,比如数字2的二进制表示是:00010,一共有5个基因,
我们这里x的取值范围是[0,31],也就是为了将基因的最大个数限制在5个,因为5个基因最大数值是:11111,转换为十进制就是31 。当然其实自己可是设置更大的基因个数,这里只是用来演示简单的过程。
适应度函数(Fitness function)
在算法的每次迭代中,使用适应度函数(也称为目标函数)对个体进行评估。目标函数是用于优化的函数或试图解决的问题。适应度得分更高【适应度可以根据目标函数的需求来设定是取大还是取小】的个体代表了更好的解,其更有可能被选择繁殖并且其性状会在下一代中得到表现。比如我们这里的适应度函数就是个体数值的平方,随着遗传算法的进行,解的质量会提高,适应度会增加,一旦找到具有令人满意的适应度值的解,终止遗传算法。
选择(Selection)
在计算出种群中每个个体的适应度后,使用选择过程来确定种群中的哪个个体将用于繁殖并产生下一代,具有较高值的个体更有可能被选中,并将其遗传物质传递给下一代。仍然有机会选择低适应度值的个体,但概率较低。这样,就不会完全摒弃其遗传物质。
交叉(Crossover)
为了创建一对新个体,通常将从当前代中选择的双亲样本的部分染色体互换(交叉),以创建代表后代的两个新染色体。此操作称为交叉或重组。
突变(Mutation)
突变操作的目的是定期随机更新种群,将新模式引入染色体,并鼓励在解空间的未知区域中进行搜索。
突变可能表现为基因的随机变化。变异是通过随机改变一个或多个染色体值来实现的。例如,翻转二进制串中的一位。
# 参数设置 CHROMOSOME_SIZE = 5 # 染色体长度 POPULATION_SIZE = 10 # 种群大小 CROSSOVER_RATE = 0.7 # 交叉率,就是有70%的概率会交叉,30%直接返回原始的基因 MUTATION_RATE = 0.01 # 变异率 GENERATIONS = 100 # 迭代次数 # 初始化种群 population = np.random.randint(2, size=(POPULATION_SIZE, CHROMOSOME_SIZE)) array([[1, 0, 0, 1, 0], [0, 1, 0, 0, 1], [0, 1, 1, 0, 1], [0, 0, 1, 1, 0], [1, 0, 0, 1, 0], [1, 0, 1, 1, 0], [1, 0, 0, 1, 1], [0, 1, 1, 0, 0], [1, 1, 0, 1, 1], [1, 0, 0, 0, 1]])
我们可以看到这里有10条数据,就是个体数为10 的种群。
# 适应度函数,计算个体的适应度 def fitness(chromosome): x = int(''.join(str(gene) for gene in chromosome), 2)#转换成十进制 return x ** 2 # 选择函数,基于适应度进行选择 def select(population): fitness_values = np.array([fitness(individual) for individual in population]) return population[np.random.choice(range(POPULATION_SIZE), size=POPULATION_SIZE, replace=True, p=fitness_values / fitness_values.sum())] # 交叉函数,随机选择交叉点,进行基因交换 def crossover(parent1, parent2): if np.random.rand() < CROSSOVER_RATE: point = np.random.randint(1, CHROMOSOME_SIZE - 1) return np.concatenate((parent1[:point], parent2[point:])), np.concatenate((parent2[:point], parent1[point:])) else: return parent1, parent2 # 变异函数,随机翻转基因 def mutate(chromosome): for i in range(CHROMOSOME_SIZE): if np.random.rand() < MUTATION_RATE: chromosome[i] = 1 - chromosome[i] return chromosome
选择函数解析:
交叉函数
变异解析
# 用于存储每代的最佳适应度,用于后续的可视化 best_fitness_over_generations = [] # 遗传算法主循环 for generation in range(GENERATIONS): selected_population = select(population) next_generation = [] for i in range(0, POPULATION_SIZE, 2): parent1, parent2 = selected_population[i], selected_population[i + 1] offspring1, offspring2 = crossover(parent1, parent2) offspring1 = mutate(offspring1) offspring2 = mutate(offspring2) next_generation.append(offspring1) next_generation.append(offspring2) population = np.array(next_generation) # 更新最佳适应度 best_fitness = max(fitness(individual) for individual in population) best_fitness_over_generations.append(best_fitness) print(f'Generation {generation + 1}, Best Fitness: {best_fitness}')
best_fitness_over_generations = []
:
for generation in range(GENERATIONS):
:
GENERATIONS
是预设的迭代次数,即算法将运行的代数。selected_population = select(population)
:
select
,根据个体的适应度比例从当前种群中选择出新的种群。next_generation = []
:
for i in range(0, POPULATION_SIZE, 2):
:
parent1, parent2 = selected_population[i], selected_population[i + 1]
:
offspring1, offspring2 = crossover(parent1, parent2)
:
crossover
,对两个父母个体进行交叉操作,生成两个子代个体。offspring1 = mutate(offspring1)
和 offspring2 = mutate(offspring2)
:
mutate
,对两个子代个体进行变异操作。next_generation.append(offspring1)
和 next_generation.append(offspring2)
:
population = np.array(next_generation)
:
best_fitness = max(fitness(individual) for individual in population)
:
best_fitness_over_generations.append(best_fitness)
:
best_fitness_over_generations
列表中,用于后续分析。print(f'Generation {generation + 1}, Best Fitness: {best_fitness}')
:
Generation 1, Best Fitness: 729
Generation 2, Best Fitness: 729
Generation 3, Best Fitness: 841
Generation 4, Best Fitness: 729
Generation 5, Best Fitness: 729
Generation 6, Best Fitness: 961
Generation 7, Best Fitness: 961
Generation 8, Best Fitness: 961
……
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。