import numpy as np
import random
import warnings
import random
import copy
import pandas as pd
import time
import matplotlib
import matplotlib.pyplot as plt
from datetime import datetime
# Función objetivo que se quiere minimizar
def funcion_objetivo(x_0, x_1):
"""
Para la región acotada entre −10<=x_0<=0 y −6.5<=x_1<=0 la función tiene
múltiples mínimos locales y un único minimo global que se encuentra en
f(−3.1302468,−1.5821422) = −106.7645367
"""
f = np.sin(x_1)*np.exp(1-np.cos(x_0))**2 \
+ np.cos(x_0)*np.exp(1-np.sin(x_1))**2 \
+ (x_0-x_1)**2
return(f)
# Gráfico 3d de la función objetivo
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
fig = plt.figure(figsize=(8.5, 6))
ax = fig.add_subplot(111, projection='3d')
# Grid de datos
x = np.arange(-10, 0, 0.05)
y = np.arange(-6.5, 0, 0.05)
x, y = np.meshgrid(x, y)
z = np.array(funcion_objetivo(np.ravel(x), np.ravel(y)))
z = z.reshape(x.shape)
grafico = ax.plot_surface(x, y, z, cmap=cm.coolwarm,
linewidth=1, antialiased=True)
ax.view_init(30, 45)
# Contour plot función objetivo
fig = plt.figure(figsize=(6, 4.2))
x_0 = np.linspace(start = -10, stop = 0, num = 100)
x_1 = np.linspace(start = -6.5, stop = 0, num = 100)
x_0, x_1 = np.meshgrid(x_0, x_1)
z = funcion_objetivo(x_0, x_1)
plt.contour(x_0, x_1, z, 35, cmap='RdGy')
# Crear población
poblacion = Poblacion(
n_individuos = 50,
n_variables = 2,
limites_inf = [-10, -6.5],
limites_sup = [0, 0],
verbose = False
)
# Optimizar
poblacion.optimizar(
funcion_objetivo = funcion_objetivo,
optimizacion = "minimizar",
n_generaciones = 250,
metodo_seleccion = "tournament",
elitismo = 0.1,
prob_mut = 0.01,
distribucion = "uniforme",
media_distribucion = 1,
sd_distribucion = 1,
min_distribucion = -1,
max_distribucion = 1,
parada_temprana = True,
rondas_parada = 10,
tolerancia_parada = 10**-16,
verbose = False
)
# Evolución de la optimización
poblacion.resultados_df['mejor_fitness'].plot(title = "Evolución del fitness")
#import matplotlib.animation as animation
#%matplotlib notebook
fig = plt.figure(figsize=(8,5))
plt.xlim(-10,0)
plt.ylim(-6.5,0)
def animate(i):
p2 = fig.clear()
plt.xlim(-10,0)
plt.ylim(-6.5,0)
df_posiciones_i = df_posiciones[df_posiciones["generacion"] == i][["x_0", "x_1"]]
p1 = plt.contour(x_0, x_1, z, 35, cmap='RdGy')
p2 = plt.scatter(df_posiciones_i["x_0"], df_posiciones_i["x_1"])
ani = matplotlib.animation.FuncAnimation(fig, animate, frames=25, blit = True)