Inicio Rápido

A continuación, se muestra un ejemplo básico de cómo utilizar la clase GA para maximizar la función \(f(x, y) = \sin(x) \cdot \cos(y) + (x+y)/10\).

examples/example_math_function_maximization.py
  1"""
  2Ejemplo de Algoritmo Genético para maximizar una función matemática continua.
  3
  4Problema: Maximizar la función f(x, y) = sin(x) * cos(y) + (x+y)/10
  5donde x e y están en el rango [-10, 10].
  6El individuo tendrá 2 genes (x, y).
  7
  8El algoritmo genético se ejecutará por 150 generaciones
  9y el mejor fitness debe aproximarse a 2.4238.
 10"""
 11
 12import numpy as np
 13
 14from PySAG import GA, crossover, initialization, mutation, selection
 15
 16# 1. Definir la función de Fitness
 17GENE_LOW = -10.0
 18GENE_HIGH = 10.0
 19NUM_GENES = 2  # Dos variables: x, y
 20
 21
 22def fitness_function(individual: np.ndarray) -> float:
 23    """
 24    Función de fitness para el problema de maximización de una función matemática.
 25
 26    Calcula el fitness de un individuo.
 27    f(x, y) = sin(x) * cos(y) + (x+y)/10
 28    Buscamos maximizar esta función.
 29    """
 30    if len(individual) != NUM_GENES:
 31        raise ValueError(f"El individuo debe tener {NUM_GENES} genes.")
 32    x = individual[0]
 33    y = individual[1]
 34
 35    # Asegurarse de que los genes estén dentro del rango
 36    # (puede ser redundante si la mutación/inicialización lo manejan)
 37    x = np.clip(x, GENE_LOW, GENE_HIGH)
 38    y = np.clip(y, GENE_LOW, GENE_HIGH)
 39
 40    return np.sin(x) * np.cos(y) + (x + y) / 10.0
 41
 42
 43# 2. Configurar y Instanciar la clase GA
 44population_size = 100
 45num_generations = 150
 46num_parents_mating = 20
 47crossover_prob = 0.85
 48elitism_percentage = 0.05
 49mutation_rate_for_gaussian = 0.1  # Tasa de mutación por gen para la mutación Gaussiana
 50
 51print("Configurando el Algoritmo Genético para maximizar f(x,y)...")
 52
 53ga_instance_math = GA(
 54    fitness_func=fitness_function,
 55    num_genes=NUM_GENES,
 56    population_size=population_size,
 57    num_generations=num_generations,
 58    num_parents_mating=num_parents_mating,
 59    # Inicialización: Uniforme para valores flotantes
 60    initial_population_func=initialization.init_random_uniform,
 61    initial_pop_args={"low": GENE_LOW, "high": GENE_HIGH, "dtype": np.float64},
 62    # Selección: Por Torneo
 63    selection_func=selection.selection_tournament,
 64    selection_args={
 65        "tournament_size": 5
 66    },  # Argumento específico para la selección por torneo
 67    # Cruce: Uniforme
 68    crossover_func=crossover.crossover_uniform,
 69    crossover_args={"mix_probability": 0.5},  # Argumento para cruce uniforme
 70    crossover_probability=crossover_prob,
 71    # Mutación: Gaussiana
 72    mutation_func=mutation.mutation_gaussian,
 73    mutation_args={
 74        "mu": 0.0,
 75        "sigma": 0.5,  # Desviación estándar
 76        "mutation_rate": mutation_rate_for_gaussian,
 77        "gene_low": GENE_LOW,  # Límites para asegurar que la mutación no se salga
 78        "gene_high": GENE_HIGH,
 79    },
 80    keep_elitism_percentage=elitism_percentage,
 81    random_seed=42,  # Para reproducibilidad
 82)
 83
 84# 3. Ejecutar el AG
 85print("Ejecutando el Algoritmo Genético...")
 86best_solution, best_fitness = ga_instance_math.run()
 87
 88# 4. Mostrar Resultados
 89if best_solution is not None:
 90    print(f"\nMejor solución encontrada: {best_solution}")
 91    print(f"Valor de la función (fitness): {best_fitness:.6f}")
 92
 93    # Verificar el fitness recalculando
 94    recalculated_fitness = fitness_function(best_solution)
 95    print(f"Fitness recalculado para la mejor solución: {recalculated_fitness:.6f}")
 96
 97    # (Opcional) Graficar el fitness
 98    ga_instance_math.plot_fitness(save_path="math_function_maximization_fitness.png")
 99else:
100    print("No se encontró una solución.")
101
102print("\nEjemplo de maximización de función matemática completado.")