Python遗传算法代码实例讲解⽬录
实例:
求解函数的最⼤值y=xsin(10x)+xsin(2x),⾃变量取值:0--5,⽤Python画出的图像如下
(注:此代码好像有⼀些感觉不对的地⽅,⾸先:没有保留那些适应度低的个体
pop = select(pop, fitness) '''这⼀⾏代码,压根就是把适应度低的个体给⼲没了。'''
for parent in pop:
child = crossover(parent, pop_copy)
child = mutate(child)
parent[:] = child '''这个for循环,没有对交叉变异后的个体进⾏适应度筛选啊'''
)
代码讲解:
1初始化种:返回⼀个元素为⼆进制的矩阵,每⼀⾏代表⼀个个体,每个个体由⼆进制数字表⽰x值
2:代表⼆进制,POP_SIZE:矩阵⾏数,DNA_SIZE:矩阵列数。
'''
pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE))
'''
2,计算适应度并且原则优良种,(有放回的抽取),循环很多代
pop:代表⼆进制种,translateDNA(pop):将其转化⼗进制,在计算适应度,在select选择优良种
'''
F_values = F(translateDNA(pop)) #求函数值
fitness = get_fitness(F_values) #得到使⽤度,这⾥例⼦函数值就是适应度
pop = select(pop, fitness)
#此时的pop是经过筛选的好的总,也是⼀个⼆进制表现⽅式,⾥⾯有很多⼀样的个体,因为使⽤放回抓取'''
3,经过⼀波筛选后,接下来该交叉变异了,为了得到更好的x值,因为初始化的x值使得个体分布不均匀
'''
pop_copy = py() #复制⼀份优良种,⽤于交叉变异
for parent in pop:
child = crossover(parent, pop_copy) #交叉
child = mutate(child) #交叉后的种在进⾏变异
parent[:] = child
#将child赋值给parent
难度较⼤的代码:
crossover() mutate() parent[:] = child
crossover
交叉:parent:表⽰每⼀个⼆进制个体,pop:优良的种,如100个个体
返回交叉后的⼀个个体,也是⼆进制表⽰⽅式
这个函数的功能就是
parent[cross_points] = pop[i_, cross_points]
'''
def crossover(parent, pop): # mating process (genes crossover)
if np.random.rand() < CROSS_RATE:
i_ = np.random.randint(0, POP_SIZE, size=1) # select another individual from pop
# 从0-POP_SIZE,随机选择⼀个数字,
cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(np.bool)
#array([ True, False, False, True, True, False, False, True, True,
#True])
#随机⽣成⼀个10个元素的数组,元素为0和1,在转化成bool型
# choose crossover points
parent[cross_points] = pop[i_, cross_points]
#这个语句有难度:
'''
将parent为True的元素,将被改变,False的元素不变.将被改变的元素改变成 pop矩阵第 i_ ⾏⾥⾯被选择为true的元素,注意,parent的是cross_points, pop 也是cross_points,必须保持⼀致,才可以实现交叉⽣成⼀个新的个体,这个个体是⽗母基因的交叉结果'''
# mating and produce one child
return parent #将新个体返回出去
'''
变异:将交叉后得到的个体,(这个个体不⼀定就是好的个体,很可能是不好的适应度不⾼的个体)
进⾏变异,
核⼼代码:
linspace函数pythonchild[point] = 1 if child[point] == 0 else 0
'''
def mutate(child):
for point in range(DNA_SIZE):
if np.random.rand() < MUTATION_RATE:
child[point] = 1 if child[point] == 0 else 0
'''
point是把child这个个体基因遍历⼀遍,按照⼏率进⾏将0变成1,
注意:并不是将所有的0变成1,⽽是有⼏率的 if np.random.rand() < MUTATION_RATE:
'''
return child
全部代码:
"""
Visualize Genetic Algorithm to find a maximum point in a function.
Visit my tutorial website for more: morvanzhou.github.io/tutorials/
"""
import numpy as np
import matplotlib.pyplot as plt
DNA_SIZE = 10 # DNA length
POP_SIZE = 100 # population size
CROSS_RATE = 0.8 # mating probability (DNA crossover)
MUTATION_RATE = 0.003 # mutation probability
N_GENERATIONS = 200
X_BOUND = [0, 5] # x upper and lower bounds
def F(x): return np.sin(10*x)*x + np.cos(2*x)*x # to find the maximum of this function
# find non-zero fitness for selection
def get_fitness(pred): return pred + 1e-3 - np.min(pred)
# convert binary DNA to decimal and normalize it to a range(0, 5)
def translateDNA(pop): return pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2**DNA_SIZE-1) * X_BOUND[1]
def select(pop, fitness): # nature selection wrt pop's fitness
idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,
p=fitness/fitness.sum())
return pop[idx]
def crossover(parent, pop): # mating process (genes crossover)
if np.random.rand() < CROSS_RATE:
i_ = np.random.randint(0, POP_SIZE, size=1) # select another individual from pop
cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(np.bool) # choose crossover points
parent[cross_points] = pop[i_, cross_points] # mating and produce one child
return parent
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
pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE)) # initialize the pop DNA
plt.ion() # something about plotting
x = np.linspace(*X_BOUND, 200)
plt.plot(x, F(x))
for _ in range(N_GENERATIONS):
F_values = F(translateDNA(pop)) # compute function value by extracting DNA
# something about plotting
if 'sca' in globals(): ve()
sca = plt.scatter(translateDNA(pop), F_values, s=200, lw=0, c='red', alpha=0.5); plt.pause(0.05)
# GA part (evolution)
fitness = get_fitness(F_values)
print("Most fitted DNA: ", pop[np.argmax(fitness), :])
pop = select(pop, fitness)
pop_copy = py()
for parent in pop:
child = crossover(parent, pop_copy)
child = mutate(child)
parent[:] = child # parent is replaced by its child
plt.ioff(); plt.show()
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论