Python实现简单遗传算法的完整攻略
遗传算法是一种基于自然选择和遗传进化原理的优化算法,可以用于解决复杂的优化问题。本文将细讲解Python实现简单遗传算法的整个攻略,包括算法原理、实现过程和示例。
算法原理
遗传算法的基本思想是通过模拟自然界中的进化过程,将问题的解表示为染色体,通过交叉、异等操作产生新的染色体,然后根据适应度函数对染色体进行选择,使优秀的染色体得以保留,不断迭代,最终得到最优解。
具体来说,算法分为以下几个步骤:
- 初始化种群,随机生成一定数量的染色体。
- 计算每个染色体的适应度,根据适应函数对染色体进行选择。
- 通过交叉、变异等操作产生新的染色体。
- 重复步骤2-3,直到达到停止条件。
实现过程
以下是使用Python实现简单遗传算法的示例代码:
import random
class GeneticAlgorithm:
def __init__(self, population_size, chromosome_length, mutation_rate, crossover_rate, elitism):
self.population_size = population_size
self.chromosome_length = chromosome_length
self.mutation_rate = mutation_rate
self.crossover_rate = crossover_rate
self.elitism = elitism
def init_population(self):
population = []
for i in range(self.population_size):
chromosome = [random.randint(0, 1) for j in range(self.chromosome_length)]
population.append(chromosome)
return population
def fitness(self, chromosome):
return sum(chromosome)
def selection(self, population):
fitnesses = [self.fitness(chromosome) for chromosome in population]
total_fitness = sum(fitnesses)
probabilities = [fitness / total_fitness for fitness in fitnesses]
selected = random.choices(population, probabilities, k=self.population_size)
return selected
def crossover(self, parent1, parent2):
if random.random() < self.crossover_rate:
crossover_point = random.randint(1, self.chromosome_length - 1)
child1 = parent1[:crossover_point] + parent2[crossover_point:]
child2 = parent2[:crossover_point] + parent1[crossover_point:]
return child1, child2
else:
return parent1, parent2
def mutation(self, chromosome):
if random.random() < self.mutation_rate:
mutation_point = random.randint(0, self.chromosome_length - 1)
chromosome[mutation_point] = 1 - chromosome[mutation_point]
return chromosome
def evolve(self, population):
elites = sorted(population, key=self.fitness, reverse=True)[:self.elitism]
selection = self.selection(population)
offspring = []
for i in range(self.population_size - self.elitism):
parent1, parent2 = random.choices(selection, k=2)
child1, child2 = self.crossover(parent1, parent2)
child1 = self.mutation(child1)
child2 = self.mutation(child2)
offspring.append(child1)
offspring.append(child2)
population = elites + offspring
return population
上述代码中,首先定义了一个GeneticAlgorithm类,包含初始化种群、计算适应度、选择、交叉、变异和进化等方法。init_population方法中,随机生成一定数量的染色体。在fitness方法中,计算染色体的适应度。在selection方法中,根据适应度函数对染色体进行选择。在crossover方法中,根据交叉率对染色体进行交叉。在mutation方法中,根据变异率对染色体进行变异。在evolve方法中,进行进化操作。
示例1
以下是使用遗传算法求解函数最大值的示例代码:
import math
def fitness_function(x):
return math.sin(x)
ga = GeneticAlgorithm(population_size=100, chromosome_length=10, mutation_rate=0.01, crossover_rate=0.8, elitism=2)
population = ga.init_population()
for i in range(100):
population = ga.evolve(population)
best_chromosome = max(population, key=ga.fitness)
best_fitness = ga.fitness(best_chromosome)
print('Generation:', i, 'Best Fitness:', best_fitness, 'Best Solution:', best_chromosome)
上述代码中,首先定义了一个适应度函数fitness_function,用于计算函数的最大值。然后使用GeneticAlgorithm类初始化遗传算法模型,并设置种群大小、染色体长度、变异率、交叉率和精英数。接着使用init_population方法初始化种群。然后进行100次进化操作,并输出每一代的最优解。
示例2
以下是使用遗传算法求解TSP问题的示例代码:
import random
import math
class City:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self, city):
x_distance = abs(self.x - city.x)
y_distance = abs(self.y - city.y)
distance = math.sqrt(x_distance ** 2 + y_distance ** 2)
return distance
class Route:
def __init__(self, cities):
self.cities = cities
self.distance = self.calculate_distance()
def calculate_distance(self):
distance = 0
for i in range(len(self.cities) - 1):
distance += self.cities[i].distance(self.cities[i + 1])
distance += self.cities[-1].distance(self.cities[0])
return distance
class GeneticAlgorithm:
def __init__(self, population_size, mutation_rate, crossover_rate, elitism):
self.population_size = population_size
self.mutation_rate = mutation_rate
self.crossover_rate = crossover_rate
self.elitism = elitism
def init_population(self, cities):
population = []
for i in range(self.population_size):
route = Route(random.sample(cities, len(cities)))
population.append(route)
return population
def fitness(self, route):
return 1 / route.distance
def selection(self, population):
fitnesses = [self.fitness(route) for route in population]
total_fitness = sum(fitnesses)
probabilities = [fitness / total_fitness for fitness in fitnesses]
selected = random.choices(population, probabilities, k=self.population_size)
return selected
def crossover(self, parent1, parent2):
if random.random() < self.crossover_rate:
crossover_point1 = random.randint(1, len(parent1.cities) - 1)
crossover_point2 = random.randint(crossover_point1, len(parent1.cities) - 1)
child1_cities = parent1.cities[:crossover_point1] + parent2.cities[crossover_point1:crossover_point2] + parent1.cities[crossover_point2:]
child2_cities = parent2.cities[:crossover_point1] + parent1.cities[crossover_point1:crossover_point2] + parent2.cities[crossover_point2:]
child1 = Route(child1_cities)
child2 = Route(child2_cities)
return child1, child2
else:
return parent1, parent2
def mutation(self, route):
if random.random() < self.mutation_rate:
mutation_point1 = random.randint(0, len(route.cities) - 1)
mutation_point2 = random.randint(0, len(route.cities) - 1)
route.cities[mutation_point1], route.cities[mutation_point2] = route.cities[mutation_point2], route.cities[mutation_point1]
return route
def evolve(self, population):
elites = sorted(population, key=self.fitness, reverse=True)[:self.elitism]
selection = self.selection(population)
offspring = []
for i in range(self.population_size - self.elitism):
parent1, parent2 = random.choices(selection, k=2)
child1, child2 = self.crossover(parent1, parent2)
child1 = self.mutation(child1)
child2 = self.mutation(child2)
offspring.append(child1)
offspring.append(child2)
population = elites + offspring
return population
cities = [City(60, 200), City(180, 200), City(80, 180), City(140, 180), City(20, 160), City(100, 160), City(200, 160), City(140, 140), City(40, 120), City(100, 120), City(180, 100), City(60, 80), City(120, 80), City(180, 60), City(20, 40), City(100, 40), City(200, 40), City(20, 20), City(60, 20), City(160, 20)]
ga = GeneticAlgorithm(population_size=100, mutation_rate=0.01, crossover_rate=0.8, elitism=2)
population = ga.init_population(cities)
for i in range(100):
population = ga.evolve(population)
best_route = max(population, key=ga.fitness)
best_distance = best_route.distance
print('Generation:', i, 'Best Distance:', best_distance)
上述代码中,首先定义了一个City类和Route类,用于表示城市和路径。然后使用GeneticAlgorithm类初始化遗传算模型,并设置种群大小、变异率、交叉率和精英数。接着使用init_population方法初始化种群。然后进行100次进化操作,并输出每一代的最优解。
总结
本文详细讲解了Python实现简单遗传算法的整个攻略,包括算法原理实现过程和示例。遗传算法是一种基于自然选择和遗传进化原理的优化算法,可以用于解决复杂的优化问题。Python中,可以使用random模块实现遗传算法,实现程上述所示。通过示例看到遗传算法在实际应用中的灵活性和实用性。