Эволюционное развлечение: угадывание строк с помощью генетических алгоритмов

Генетические алгоритмы – это мощные методы оптимизации, основанные на принципах естественного отбора и генетики. Эти алгоритмы можно применять к различным проблемным областям, включая угадывание строк. В этой статье мы рассмотрим различные методы угадывания целевой строки с использованием генетического алгоритма. Мы предоставим примеры кода на Python, чтобы проиллюстрировать каждый подход. Итак, приступим!

Метод 1: случайная генерация
Самый простой способ угадать строку с помощью генетического алгоритма — начать со случайно сгенерированной совокупности строк. Каждая строка в популяции представляет отдельного человека. Затем алгоритм итеративно развивает популяцию, отбирая наиболее приспособленных особей, применяя генетические операторы, такие как скрещивание и мутация, и создавая следующее поколение. Вот пример реализации:

import random
target_string = "Hello, World!"
population_size = 100
mutation_rate = 0.01
def generate_random_string(length):
    return ''.join(random.choice(string.ascii_letters + " ,!") for _ in range(length))
def calculate_fitness(individual):
    fitness = sum(1 for expected, actual in zip(target_string, individual) if expected == actual)
    return fitness / len(target_string)
def crossover(parent1, parent2):
    crossover_point = random.randint(1, len(target_string) - 1)
    child = parent1[:crossover_point] + parent2[crossover_point:]
    return child
def mutate(individual):
    mutated_individual = ""
    for char in individual:
        if random.random() < mutation_rate:
            mutated_individual += random.choice(string.ascii_letters + " ,!")
        else:
            mutated_individual += char
    return mutated_individual
def evolve_population(population):
    next_generation = []
    population_fitness = [calculate_fitness(individual) for individual in population]
    fittest_individuals = sorted(range(len(population_fitness)), key=lambda i: population_fitness[i], reverse=True)[:10]
    for _ in range(population_size):
        parent1 = population[random.choice(fittest_individuals)]
        parent2 = population[random.choice(fittest_individuals)]
        child = crossover(parent1, parent2)
        child = mutate(child)
        next_generation.append(child)
    return next_generation
def genetic_algorithm():
    population = [generate_random_string(len(target_string)) for _ in range(population_size)]
    generation = 1
    while True:
        best_individual = max(population, key=calculate_fitness)
        if best_individual == target_string:
            return best_individual, generation
        print(f"Generation: {generation}\tBest individual: {best_individual}")
        population = evolve_population(population)
        generation += 1
best_individual, generation = genetic_algorithm()
print(f"Found target string '{best_individual}' in generation {generation}.")

Метод 2: Элитизм
В этом подходе мы вводим элитарность, сохраняя определенное количество наиболее приспособленных особей от одного поколения к другому без применения каких-либо генетических операторов. Это гарантирует, что лучшие решения не будут потеряны в процессе эволюции. Вот пример реализации:

# ... (Same code as Method 1 until evolve_population function)
def evolve_population(population):
    next_generation = []
    population_fitness = [calculate_fitness(individual) for individual in population]
    fittest_individuals = sorted(range(len(population_fitness)), key=lambda i: population_fitness[i], reverse=True)[:10]
    for i in fittest_individuals:
        next_generation.append(population[i])
    for _ in range(population_size - len(fittest_individuals)):
        parent1 = population[random.choice(fittest_individuals)]
        parent2 = population[random.choice(fittest_individuals)]
        child = crossover(parent1, parent2)
        child = mutate(child)
        next_generation.append(child)
    return next_generation
# ... (Same code as Method 1 after evolve_population function)
best_individual, generation = genetic_algorithm()
print(f"Found target string '{best_individual}' in generation {generation}.")

В этой статье мы рассмотрели два метода угадывания целевой строки с помощью генетического алгоритма. Первый метод включал случайную генерацию, а второй метод ввел элитарность для сохранения наиболее приспособленных особей. Эти примеры демонстрируют мощь и универсальность генетических алгоритмов при решении задач оптимизации. Не стесняйтесь экспериментировать с различными параметрами и вариациями, чтобы улучшить производительность алгоритмов.