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
import numpy as np
import matplotlib.pyplot as plt

DNA_SIZE=10
POP_SIZE=100
CROSS_RATE=0.8
MUTATION_RATE=0.003
N_GENERATIONS=200
X_BOUND=[0,5]

#定义目标函数
def F(x):
return np.sin(10*x)*x+np.cos(2*x)*x

#计算适应度,并使其大于0
def get_fitness(pred):
return pred+1e-3-np.min(pred)

#将二进制串的DNA转为10进制数并限制范围在0到5之间
def translateDNA(population):
return population.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE)*X_BOUND[1]

#根据种群中个体适应度做自然选择
def select(population,fitness):
idx=np.random.choice(np.arange(POP_SIZE),size=POP_SIZE,replace=True,p=fitness/fitness.sum())
return population[idx]

#交叉
def crossover(parent,population):#其实,population 与parent是一个东西
if np.random.rand()<CROSS_RATE:
i_=np.random.randint(0,POP_SIZE,size=1)#选择母本
cross_points=np.random.randint(0,2,size=DNA_SIZE).astype(np.bool)
parent[cross_points]=population[i_,cross_points]
return parent#此时的parent已经是child了

#变异
def mutate(child):
for point in range(DNA_SIZE):
if np.random.rand()<MUTATION_RATE:
child[point]=1 if child[point]==0 else 0
return child

if __name__ == '__main__':
plt.ion() # something about plotting
x = np.linspace(*X_BOUND, 200)
plt.plot(x, F(x))

population=np.random.randint(2,size=(POP_SIZE,DNA_SIZE))
for _ in range(N_GENERATIONS):
F_values=F(translateDNA(population))

# something about plotting
if 'sca' in globals(): sca.remove()
sca = plt.scatter(translateDNA(population), F_values, s=200, lw=0, c='red', alpha=0.5); plt.pause(0.05)

fitness=get_fitness(F_values)
print("Most fitted DNA: ", population[np.argmax(fitness), :])
population=select(population,fitness)
pop_copy=population.copy()
for parent in population:
child=crossover(parent,pop_copy)
child=mutate(child)
parent[:]=child#child覆盖parent,相当于进化了
plt.ioff()
plt.show()

参考:

https://github.com/MorvanZhou/Evolutionary-Algorithm/blob/master/tutorial-contents/Genetic%20Algorithm/Genetic%20Algorithm%20Basic.py