【专业课学习】Python实现简单的遗传算法

36 阅读1分钟

求解区间[0,31][0, 31]上的何值可以使得函数y=x2y=x^2的取值最大.

# Let's implement a simple genetic algorithm to solve the problem of finding the maximum value of y = x^2 in the range [0, 31].
# We will use the basic steps of genetic algorithms (GA): Initialization, Selection, Crossover, Mutation, and Evaluation.

import random

# Define the parameters of the genetic algorithm
POPULATION_SIZE = 4  # Size of the population
GENES = 5  # Number of bits for each chromosome (to represent numbers from 0 to 31)
GENERATIONS = 500  # Number of generations to evolve
CROSSOVER_RATE = 0.8  # Probability of crossover
MUTATION_RATE = 0.01  # Probability of mutation
ELITE_COUNT = 1  # Number of elite individuals to retain


# Function to decode the binary chromosome to a decimal number
def decode(chromosome):
    return int("".join(map(str, chromosome)), 2)

# Fitness function: in this case, y = x^2, we want to maximize it
def fitness(chromosome):
    x = decode(chromosome)
    return x ** 2

# Initialize the population with random binary chromosomes
def initialize_population():
    population = []
    for _ in range(POPULATION_SIZE):
        chromosome = [random.randint(0, 1) for _ in range(GENES)]
        population.append(chromosome)
    return population

# Selection function: roulette wheel selection
def selection(population):
    total_fitness = sum(fitness(individual) for individual in population)
    selection_probs = [fitness(individual) / total_fitness for individual in population]
    return population[random.choices(range(POPULATION_SIZE), weights=selection_probs)[0]]

# Crossover operation: single-point crossover
def crossover(parent1, parent2):
    if random.random() < CROSSOVER_RATE:
        point = random.randint(1, GENES - 1)
        return parent1[:point] + parent2[point:], parent2[:point] + parent1[point:]
    return parent1, parent2

# Mutation operation: flip a random bit
def mutate(chromosome):
    if random.random() < MUTATION_RATE:
        point = random.randint(0, GENES - 1)
        chromosome[point] = 1 - chromosome[point]
    return chromosome

# Elitism: retain the best individual(s) directly into the next generation
def elitism(population):
    sorted_population = sorted(population, key=fitness, reverse=True)
    return sorted_population[:ELITE_COUNT]

# Main genetic algorithm
def genetic_algorithm():
    # Step 1: Initialize population
    population = initialize_population()

    for generation in range(GENERATIONS):
        # Step 2: Selection, crossover, and mutation
        new_population = elitism(population)  # Add elite individuals to new population
        while len(new_population) < POPULATION_SIZE:
            parent1 = selection(population)
            parent2 = selection(population)
            offspring1, offspring2 = crossover(parent1, parent2)
            new_population.append(mutate(offspring1))
            if len(new_population) < POPULATION_SIZE:
                new_population.append(mutate(offspring2))

        population = new_population

        # Print the best solution in this generation
        best_individual = max(population, key=fitness)
        best_value = decode(best_individual)
        best_fitness = fitness(best_individual)
        print(f"Generation {generation + 1}: Best x = {best_value}, y = x^2 = {best_fitness}")

# Run the genetic algorithm
genetic_algorithm()