遗传算法是一种模拟自然选择和遗传变异机制的启发式优化算法,通过迭代进化种群来寻找目标函数的最优解,结合进化策略可以进一步提升全局优化的效率和精度,尤其适合处理非线性、多峰值的复杂目标函数优化问题。

核心概念说明
在正式实现前,需要先明确几个核心概念:
- 种群:由多个个体组成的集合,每个个体对应目标函数的一个潜在解
- 适应度:衡量个体优劣的指标,通常直接取目标函数的计算结果,适应度越高表示解越优
- 进化策略:在遗传算法的基础上,加入自适应调整变异概率、交叉概率等参数的机制,让算法在迭代过程中动态优化搜索策略
Python实现步骤
1. 定义目标函数
这里以经典的多峰值函数为例,目标是找到函数的最大值:
import numpy as np
# 定义目标函数,这里使用Rastrigin函数,是多峰值全局优化的常用测试函数
def target_func(x):
# x是长度为2的数组,对应二维输入
return 20 + x[0]**2 + x[1]**2 - 10 * (np.cos(2 * np.pi * x[0]) + np.cos(2 * np.pi * x[1]))
2. 种群初始化
随机生成初始种群,每个个体的取值需要在目标函数的定义域范围内:
def init_population(pop_size, dim, lower_bound, upper_bound):
# pop_size:种群大小
# dim:个体维度,对应目标函数输入参数的个数
# lower_bound:每个维度的取值下界
# upper_bound:每个维度的取值上界
population = np.random.uniform(lower_bound, upper_bound, (pop_size, dim))
return population
3. 适应度计算
计算每个个体的适应度,这里直接使用目标函数的返回值作为适应度:
def calc_fitness(population):
fitness = []
for individual in population:
fitness.append(target_func(individual))
return np.array(fitness)
4. 选择操作
采用锦标赛选择法,从种群中随机选取若干个个体,保留适应度最高的个体进入下一代:
def selection(population, fitness, tournament_size=3):
new_population = []
pop_size = len(population)
for _ in range(pop_size):
# 随机选取tournament_size个个体的索引
idx = np.random.choice(pop_size, tournament_size, replace=False)
# 选取适应度最高的个体
best_idx = idx[np.argmax(fitness[idx])]
new_population.append(population[best_idx].copy())
return np.array(new_population)
5. 交叉操作
采用模拟二进制交叉,结合进化策略动态调整交叉分布指数:
def crossover(parent1, parent2, crossover_prob, eta_c):
# eta_c是交叉分布指数,属于进化策略的自适应参数
if np.random.random() > crossover_prob:
return parent1.copy(), parent2.copy()
child1 = parent1.copy()
child2 = parent2.copy()
dim = len(parent1)
for i in range(dim):
if np.random.random() > 0.5:
continue
u = np.random.random()
if u <= 0.5:
beta = (2 * u) ** (1 / (eta_c + 1))
else:
beta = (1 / (2 * (1 - u))) ** (1 / (eta_c + 1))
child1[i] = 0.5 * ((1 + beta) * parent1[i] + (1 - beta) * parent2[i])
child2[i] = 0.5 * ((1 - beta) * parent1[i] + (1 + beta) * parent2[i])
return child1, child2
6. 变异操作
采用多项式变异,同样结合进化策略动态调整变异分布指数:
def mutation(individual, mutation_prob, eta_m, lower_bound, upper_bound):
# eta_m是变异分布指数,属于进化策略的自适应参数
dim = len(individual)
for i in range(dim):
if np.random.random() > mutation_prob:
continue
u = np.random.random()
if u <= 0.5:
delta = (2 * u) ** (1 / (eta_m + 1)) - 1
else:
delta = 1 - (2 * (1 - u)) ** (1 / (eta_m + 1))
individual[i] += delta * (upper_bound - lower_bound)
# 保证个体取值在定义域内
individual[i] = np.clip(individual[i], lower_bound, upper_bound)
return individual
7. 进化策略参数自适应调整
根据迭代过程中的种群适应度方差,动态调整交叉概率和变异概率:
def adjust_params(fitness, crossover_prob, mutation_prob, gen, max_gen):
# 计算适应度方差
fitness_var = np.var(fitness)
# 迭代前期保持较高的交叉和变异概率,扩大搜索范围
# 迭代后期降低概率,细化搜索
new_crossover_prob = crossover_prob * (1 - gen / max_gen) + 0.5 * (gen / max_gen)
new_mutation_prob = mutation_prob * (1 - gen / max_gen) + 0.05 * (gen / max_gen)
return new_crossover_prob, new_mutation_prob
8. 完整算法流程
将上述步骤整合,完成完整的遗传算法全局优化流程:
def genetic_algorithm(
pop_size=50,
dim=2,
lower_bound=-5.12,
upper_bound=5.12,
max_gen=100,
init_crossover_prob=0.9,
init_mutation_prob=0.1,
init_eta_c=20,
init_eta_m=20
):
# 初始化种群
population = init_population(pop_size, dim, lower_bound, upper_bound)
best_fitness_history = []
for gen in range(max_gen):
# 计算适应度
fitness = calc_fitness(population)
# 记录当前代的最优适应度
best_fitness = np.max(fitness)
best_fitness_history.append(best_fitness)
# 调整进化策略参数
crossover_prob, mutation_prob = adjust_params(
fitness, init_crossover_prob, init_mutation_prob, gen, max_gen
)
# 选择操作
selected_pop = selection(population, fitness)
new_population = []
# 交叉操作
for i in range(0, pop_size, 2):
parent1 = selected_pop[i]
parent2 = selected_pop[i+1] if i+1 < pop_size else selected_pop[0]
child1, child2 = crossover(parent1, parent2, crossover_prob, init_eta_c)
new_population.append(child1)
new_population.append(child2)
# 变异操作
for i in range(pop_size):
new_population[i] = mutation(
new_population[i], mutation_prob, init_eta_m, lower_bound, upper_bound
)
population = np.array(new_population)
# 返回最终的最优解和适应度变化历史
final_fitness = calc_fitness(population)
best_idx = np.argmax(final_fitness)
best_solution = population[best_idx]
return best_solution, target_func(best_solution), best_fitness_history
运行与结果验证
调用上述实现的算法,查看优化结果:
if __name__ == "__main__":
best_sol, best_val, history = genetic_algorithm()
print("最优解:", best_sol)
print("最优值:", best_val)
# 理论最优解为[0,0],最优值为0
print("理论最优值:0")
运行后可以看到,随着迭代次数增加,适应度逐渐收敛到理论最优值附近,说明结合进化策略的遗传算法能够有效完成目标函数的全局优化,避免陷入局部最优解。
注意事项
- 目标函数的定义域需要和初始化时的上下界匹配,否则可能生成无效解
- 进化策略的参数调整规则可以根据具体问题修改,比如对于高维问题可以适当提高变异概率
- 如果目标函数计算成本较高,可以适当减小种群大小和迭代次数,平衡优化效果和计算效率