1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| """ Visualize Microbial Genetic Algorithm to find the maximum point in a graph. Visit my tutorial website for more: https://morvanzhou.github.io/tutorials/ """ import numpy as np import matplotlib.pyplot as plt
DNA_SIZE = 10 POP_SIZE = 20 CROSS_RATE = 0.6 MUTATION_RATE = 0.01 N_GENERATIONS = 200 X_BOUND = [0, 5]
def F(x): return np.sin(10*x)*x + np.cos(2*x)*x
class MGA(object): def __init__(self, DNA_size, DNA_bound, cross_rate, mutation_rate, pop_size): self.DNA_size = DNA_size DNA_bound[1] += 1 self.DNA_bound = DNA_bound self.cross_rate = cross_rate self.mutate_rate = mutation_rate self.pop_size = pop_size
self.pop = np.random.randint(*DNA_bound, size=(1, self.DNA_size)).repeat(pop_size, axis=0)
def translateDNA(self, pop): return pop.dot(2 ** np.arange(self.DNA_size)[::-1]) / float(2 ** self.DNA_size - 1) * X_BOUND[1]
def get_fitness(self, product): return product
def crossover(self, loser_winner): cross_idx = np.empty((self.DNA_size,)).astype(np.bool) for i in range(self.DNA_size): cross_idx[i] = True if np.random.rand() < self.cross_rate else False loser_winner[0, cross_idx] = loser_winner[1, cross_idx] return loser_winner
def mutate(self, loser_winner): mutation_idx = np.empty((self.DNA_size,)).astype(np.bool) for i in range(self.DNA_size): mutation_idx[i] = True if np.random.rand() < self.mutate_rate else False loser_winner[0, mutation_idx] = ~loser_winner[0, mutation_idx].astype(np.bool) return loser_winner
def evolve(self, n): for _ in range(n): sub_pop_idx = np.random.choice(np.arange(0, self.pop_size), size=2, replace=False) sub_pop = self.pop[sub_pop_idx] product = F(self.translateDNA(sub_pop)) fitness = self.get_fitness(product) loser_winner_idx = np.argsort(fitness) loser_winner = sub_pop[loser_winner_idx] loser_winner = self.crossover(loser_winner) loser_winner = self.mutate(loser_winner) self.pop[sub_pop_idx] = loser_winner
DNA_prod = self.translateDNA(self.pop) pred = F(DNA_prod) return DNA_prod, pred
plt.ion() x = np.linspace(*X_BOUND, 200) plt.plot(x, F(x))
ga = MGA(DNA_size=DNA_SIZE, DNA_bound=[0, 1], cross_rate=CROSS_RATE, mutation_rate=MUTATION_RATE, pop_size=POP_SIZE)
for _ in range(N_GENERATIONS): DNA_prod, pred = ga.evolve(5)
if 'sca' in globals(): sca.remove() sca = plt.scatter(DNA_prod, pred, s=200, lw=0, c='red', alpha=0.5); plt.pause(0.05)
plt.ioff();plt.show()
|