import random class DE: def __init__(self, factory, fitness, popsize = 20, F = 0.5, CR = 0.6): self.factory = factory self.fitness = fitness self.popsize = popsize self.F = F self.CR = CR self.pop = [factory() for i in range(popsize)] self.fitnesses = [fitness(x) for x in self.pop] def iterate(self): new = [] for i in range(self.popsize): while True: i1, i2, i3 = random.sample(range(self.popsize), 3) if all(x != i for x in [i1, i2, i3]): break x = self.pop[i] x1 = self.pop[i1] x2 = self.pop[i2] x3 = self.pop[i3] cand = [x1[k] + self.F * (x2[k] - x3[k]) for k in range(len(x))] X = [self.crossover(x[k], cand[k]) for k in range(len(x))] fit = self.fitness(X) if fit > self.fitnesses[i]: self.fitnesses[i] = fit new.append(X) else: new.append(x) self.pop = new def crossover(self, x1, x2): if random.random() < self.CR: return x1 else: return x2 def get_best(self): return max(zip(self.fitnesses, self.pop)) def fitness(indiv): sum = 0 for i in indiv: sum += i * i return 1 / sum def inicializa(): return [random.uniform(-10, 10) for i in range(9)] import math f = math.tanh def ann(ind, i1, i2): w1,w2,w3,w4,w5,w6,b1,b2,b3=ind m1 = f(w1*i1+w3*i2+b1) m2 = f(w2*i1+w4*i2+b2) o = f(m1 * w5 + m2 * w6 + b3) return o def fitann(ind): sum = 1e-6 + ( ( 1 - ann(ind, -1, -1)) ** 2 + (-1 - ann(ind, -1, 1)) ** 2 + (-1 - ann(ind, 1, -1)) ** 2 + ( 1 - ann(ind, 1, 1)) ** 2) return 1 / sum de = DE(inicializa, fitann) de.iterate() maxit = 100 fitnesses = [de.get_best()[0]] for i in range(maxit): de.iterate() fitnesses.append(de.get_best()[0]) import matplotlib.pyplot as plt plt.plot(range(maxit + 1), fitnesses, '.-') plt.show() print('{:e}'.format(de.get_best()[0]))