python实现简单遗传算法

  • Post category:Python

Python实现简单遗传算法的完整攻略

遗传算法是一种基于自然选择和遗传进化原理的优化算法,可以用于解决复杂的优化问题。本文将细讲解Python实现简单遗传算法的整个攻略,包括算法原理、实现过程和示例。

算法原理

遗传算法的基本思想是通过模拟自然界中的进化过程,将问题的解表示为染色体,通过交叉、异等操作产生新的染色体,然后根据适应度函数对染色体进行选择,使优秀的染色体得以保留,不断迭代,最终得到最优解。

具体来说,算法分为以下几个步骤:

  1. 初始化种群,随机生成一定数量的染色体。
  2. 计算每个染色体的适应度,根据适应函数对染色体进行选择。
  3. 通过交叉、变异等操作产生新的染色体。
  4. 重复步骤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模块实现遗传算法,实现程上述所示。通过示例看到遗传算法在实际应用中的灵活性和实用性。