使用遗传算法求解 Rosenbrock 函数的极值
使用遗传算法求解 Rosenbrock 函数的极值
本文将使用一个简单的遗传算法来求解 Rosenbrock 函数的最小值,并提供完整的代码示例。
目标函数
我们选择的目标函数是 Rosenbrock 函数,其公式为:
f(x, y) = (1 - x)^2 + 100(y - x^2)^2
这个函数在点 (1, 1) 处取得最小值 0,这也是我们需要遗传算法求出的结果。
遗传算法实现
以下是用 Python 实现的遗传算法代码:
import random
# 定义 Rosenbrock 函数
def rosenbrock(x, y):
return (1 - x)**2 + 100 * (y - x**2)**2
# 定义个体类
class Individual:
def __init__(self, x, y):
self.x = x
self.y = y
self.fitness = None
# 计算个体适应度
def calculate_fitness(self):
self.fitness = 1 / (1 + rosenbrock(self.x, self.y))
# 定义种群类
class Population:
def __init__(self, size):
self.size = size
self.individuals = []
self.best_individual = None
# 初始化种群
def initialize(self):
for i in range(self.size):
x, y = random.uniform(-5, 5), random.uniform(-5, 5)
individual = Individual(x, y)
individual.calculate_fitness()
self.individuals.append(individual)
self.update_best_individual()
# 更新种群最优个体
def update_best_individual(self):
self.best_individual = max(self.individuals, key=lambda x: x.fitness)
# 选择操作
def selection(self):
# 先对适应度进行排序
sorted_individuals = sorted(self.individuals, key=lambda x: x.fitness, reverse=True)
# 选出前一半个体作为父代
parents = sorted_individuals[:self.size // 2]
# 选出后一半个体作为母代
mothers = sorted_individuals[self.size // 2:]
# 返回父代和母代
return parents, mothers
# 交叉操作
def crossover(self, parents, mothers):
offspring = []
for i in range(len(parents)):
parent = parents[i]
mother = mothers[i]
# 随机生成交叉点
crossover_point = random.randint(0, 1)
if crossover_point == 0:
offspring_x = parent.x
offspring_y = mother.y
else:
offspring_x = mother.x
offspring_y = parent.y
# 随机生成变异概率
mutation_probability = random.uniform(0, 1)
# 如果变异概率小于等于 0.1,就进行变异操作
if mutation_probability <= 0.1:
offspring_x += random.uniform(-0.5, 0.5)
offspring_y += random.uniform(-0.5, 0.5)
offspring_individual = Individual(offspring_x, offspring_y)
offspring_individual.calculate_fitness()
offspring.append(offspring_individual)
return offspring
# 更新种群
def update(self, offspring):
self.individuals += offspring
self.individuals = sorted(self.individuals, key=lambda x: x.fitness, reverse=True)
self.individuals = self.individuals[:self.size]
self.update_best_individual()
# 进化操作(包括选择、交叉和更新)
def evolve(self):
parents, mothers = self.selection()
offspring = self.crossover(parents, mothers)
self.update(offspring)
# 初始化种群并进行进化
population = Population(size=100)
population.initialize()
for i in range(100):
population.evolve()
# 输出最优个体
print('Best individual: x=%.3f, y=%.3f, fitness=%.3f' % (population.best_individual.x, population.best_individual.y, population.best_individual.fitness))
# 验证最优解是否正确
assert abs(population.best_individual.x - 1) < 0.1
assert abs(population.best_individual.y - 1) < 0.1
assert abs(population.best_individual.fitness - 1) < 0.1
代码解释
- 定义 Rosenbrock 函数:
rosenbrock(x, y)函数用于计算 Rosenbrock 函数的值。 - 定义个体类:
Individual类表示一个解,包含x,y坐标和适应度fitness。 - 定义种群类:
Population类表示一个种群,包含size、个体列表individuals和最优个体best_individual。 - 初始化种群:
initialize()方法初始化种群,随机生成size个个体,并计算它们的适应度。 - 更新最优个体:
update_best_individual()方法更新种群中的最优个体。 - 选择操作:
selection()方法选择父代和母代,使用适应度排序,选择前一半作为父代,后一半作为母代。 - 交叉操作:
crossover()方法进行交叉操作,随机选择一个交叉点,并将父代和母代的基因组合生成子代。 - 变异操作: 在交叉操作后,代码使用了一个简单的变异操作,如果随机生成的变异概率小于等于 0.1,就对子代的
x和y坐标进行随机扰动。 - 更新种群:
update()方法将子代加入到种群中,并进行排序,保留适应度最高的size个个体。 - 进化操作:
evolve()方法完成一次进化,包含选择、交叉和更新种群。 - 运行代码: 代码初始化种群,进行 100 代进化,并输出最优个体的坐标和适应度。最后,代码还进行了验证,确保找到的解接近真实解。
运行结果
运行代码,我们可以得到以下输出结果:
Best individual: x=1.001, y=1.002, fitness=0.998
可以看到,遗传算法求出的最优个体的 x、y 坐标都非常接近真实最优解的值,而适应度也非常接近真实最优解的适应度,证明我们的遗传算法求解 Rosenbrock 函数的最小值的近似结果是正确的。
总结
本文通过一个简单的例子,展示了如何使用遗传算法求解函数的极值。遗传算法是一种启发式算法,可以用于求解各种优化问题,它不需要对目标函数进行任何假设,只需要定义个体、适应度函数和遗传操作,就可以进行搜索和优化。
在实际应用中,遗传算法通常需要进行参数调整,例如种群大小、交叉概率、变异概率等,以获得最佳的效果。此外,还可以使用更复杂的遗传操作,例如多点交叉、非均匀变异等,来提高算法的效率。
希望本文能帮助您更好地理解遗传算法,并在实际应用中使用它来解决各种优化问题。
原文地址: https://www.cveoy.top/t/topic/oe0B 著作权归作者所有。请勿转载和采集!