import numpy as np
from itertools import product
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def peaks(x):
x = x.T
F = 3*(1-x[0])**2 * np.exp(-(x[0]**2) - (x[1]+1)**2) - 10*(x[0]/5 - x[0]**3 - x[1]**5) * np.exp(-x[0]**2-x[1]**2) - 1/3*np.exp(-(x[0]+1)**2 - x[1]**2)
return F
x1 = x2 = np.linspace(-2, 2, 150)
x_p = np.array(list(product(x1,x2)))
font_labels = {'fontsize': 14, 'fontweight': 150}
fig = plt.figure(figsize=(12,8))
ax = Axes3D(fig)
ax.set_title('Função Peaks', fontdict={'fontsize':15})
ax.set_xlabel('X1', fontdict=font_labels)
ax.set_ylabel('X2', fontdict=font_labels)
ax.set_zlabel('peaks(X1, X2)', fontdict=font_labels)
surf = ax.plot_trisurf(x_p[:, 0], x_p[:, 1], [peaks(x_) for x_ in x_p], linewidth=0.1, color='orange')
plt.show()
def rastrigin(x):
x = x.reshape(1, -1).T
Q = np.eye(len(x))
X = Q.dot(x)
n = len(X)
F = 0
for i in range(n):
F = F + X[i]**2 - 10*np.cos(2*np.pi*X[i])
return F[0]
x1 = x2 = np.linspace(-3, 3, 150)
x_p = np.array(list(product(x1,x2)))
font_labels = {'fontsize': 14, 'fontweight': 150}
fig = plt.figure(figsize=(12,8))
ax = Axes3D(fig)
ax.set_title('Função Rastrigin', fontdict={'fontsize':15})
ax.set_xlabel('X1', fontdict=font_labels)
ax.set_ylabel('X2', fontdict=font_labels)
ax.set_zlabel('peaks(X1, X2)', fontdict=font_labels)
surf = ax.plot_trisurf(x_p[:, 0], x_p[:, 1], [rastrigin(x_) for x_ in x_p], linewidth=0.1, color='orange')
plt.show()
def first_population(sample_space=[(-3,3)]*2 , dimensions=2, population_size=100):
min_b, max_b = np.asarray(sample_space).T
diff = np.fabs(min_b - max_b)
population = np.random.rand(population_size, dimensions)
return min_b + population * diff
def fitness_function_eval(func,population):
return np.asarray([func(ind) for ind in population])
def best_individual_with_index(fitness_eval,population):
best_index = np.argmin(fitness_eval)
best = population[best_index]
return best,best_index
def generate_mutant(target_index,population,clip_values=[-3,3],F = 1.2,population_size = 100):
idxs = [idx for idx in range(population_size) if idx != target_index]
r1, r2,r3 = population[np.random.choice(idxs, 3, replace = False)]
return np.clip(r1 + F * (r2 - r3), clip_values[0], clip_values[1])
best_per_interaction = [] #Somente para fins de plot!
def diff_evolution(func_obj,clip_values = [-3,3],sample_space=[(-3,3)]*2, mut=0.8, crossover_probability=0.7, population_size=100, dimensions=2, iterations=1000):
population_denorm = first_population(sample_space)
fitness = fitness_function_eval(peaks,population_denorm)
best,best_index = best_individual_with_index(fitness,population_denorm)
best_per_interaction.append(best)
for i in range(iterations):
for j in range(population_size):
mutant = generate_mutant(j,population_denorm,clip_values)
crossover_points = np.random.rand(dimensions) < crossover_probability
if not np.any(crossover_points):
crossover_points[np.random.randint(0, dimensions)] = True
trial = np.array([mutant[x] if crossover_points[x] else population_denorm[j][x] for x in range(len(crossover_points))])
f = func_obj(trial)
if f < fitness[j]:
fitness[j] = f
population_denorm[j] = trial
if f < fitness[best_index]:
best_index = j
best = trial
best_per_interaction.append(best)
return best, fitness[best_index]
diff_evolution(peaks,[-3,3],[(-3,3)]*2)
import seaborn as sns
import pandas as pd
from scipy.spatial import distance
best_individual = [ 0.22827892, -1.62553496]
distances_between_gen = [distance.euclidean(x,best_individual) for x in best_per_interaction]
df = pd.DataFrame(data=distances_between_gen, columns=["distances"])
meanValue: float = df["distances"].sum() / df.size
df["above_average"] = [x > meanValue for x in df["distances"]]
fig_dims = (10, 10)
fig, ax = plt.subplots(figsize=fig_dims)
sns.scatterplot(x=df.index, y="distances", style="above_average", data=df, ax=ax)
diff_evolution(rastrigin,[-2,2],[(-2,2)]*2)
import seaborn as sns
import pandas as pd
from scipy.spatial import distance
best_individual = [0,0]
distances_between_gen = [distance.euclidean(x,best_individual) for x in best_per_interaction]
df = pd.DataFrame(data=distances_between_gen, columns=["distances"])
meanValue: float = df["distances"].sum() / df.size
df["above_average"] = [x > meanValue for x in df["distances"]]
fig_dims = (10, 10)
fig, ax = plt.subplots(figsize=fig_dims)
sns.scatterplot(x=df.index, y="distances", style="above_average", data=df, ax=ax)