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.")