python实现遗传算法求解函数极值问题
import random
import numpy as np
#定义染色体类
class chromosome:
def __init__(self,chrom,decode,fitness):
self.chrom = chrom
self.decode = decode
self.fitness = fitness
#解码函数
def decode(chom):
chom.reverse()
x = 0
for i in range(len(chom)):
x = x + chom[i]*(pow(2,i))
x1 = x * (10/pow(2,10)-1)
return x1
#适应度值(就是函数的y)
def fitness(x):
return x + 10 * np.sin(5 * x) + 7 * np.cos(4 * x)
#初始化种群
import random
def initPopulation(N):
pop = []
for i in range(N):
L=[random.randint(0,1) for i in range(10)]
this_decode = decode(L)
# print(this_decode)
this_fitness = fitness(this_decode)
pop.append(chromosome(L,this_decode,this_fitness))
# print(this_decode)
# print(this_fitness)
return pop
#交叉(两点交叉,执行基于概率Pc的两点交叉操作,采用奇偶交叉,即第1个和第2个交叉,第3个和第4个交叉,依次进行)
def crossover(pop):
odd = pop[0::2]
even = pop[1::2]
new_pop = []
a, b = np.random.choice(len(pop[0].chrom), 2)
# print(a,b)
for i in range(len(odd)):
a1 = odd[i].chrom
a2 = even[i].chrom
# print(a1,a2,"_________")
if a<b:
a1_1 = a1[0:a] + a2[a:b-1] + a1[b-1:]
a2_1 = a2[0:a] + a1[a:b-1] + a2[b-1:]
elif a>b:
a1_1 = a1[0:b] + a2[b:a-1] + a1[a-1:]
a2_1 = a2[0:b] + a1[b:a-1] + a2[a-1:]
elif a == b:
a1_1 = a1
a2_1 = a2
this_decode1 = decode(a1_1)
this_fitness1 = fitness(this_decode1)
new_pop.append(chromosome(a1_1,this_decode1,this_fitness1))
this_decode2 = decode(a2_1)
this_fitness2 = fitness(this_decode2)
new_pop.append(chromosome(a2_1,this_decode2,this_fitness2))
# print(a1_1,a2_1)
# print(len(new_pop))
return new_pop
#变异操作(执行基于概率Pm的变异操作,即随机选择一个基因位置取反,若是0则变为1,若是1则变为0)
def mutation(pop):
new_pop = []
a = np.random.choice(len(pop[0].chrom), 1)
# print(a[0])
for i in range(len(pop)):
a1 = pop[i].chrom
if a1[a[0]] == 1:
a1[a[0]] = a1[a[0]]-1
else:
a1[a[0]] = a1[a[0]]+1
this_decode = decode(a1)
this_fitness = fitness(this_decode)
new_pop.append(chromosome(a1,this_decode,this_fitness))
return new_pop
#对进化后的混合种群按适应度值排序,留下其中的适应度值高的N(此处定义的是20)个
'''
def Asort(POP):
for i in range(len(POP)):
for j in range(len(POP)-1):
if POP[i].fitness>POP[j].fitness:
POP[i],POP[j] = POP[j],POP[i]
return POP
'''
#冒泡排序
def Asort(POP):
for i in range(len(POP)):
for j in range(len(POP)-1):
# print(open_[i])
if POP[i].fitness<POP[j].fitness:
POP[i],POP[j] = POP[j],POP[i]
return POP
#进行进化选择操作,以此迭代。
def implement():
# 种群中个体数量
N = 20
# 种群
# POP = []
# 迭代次数
iter_N = 100
# 初始化种群
POP = initPopulation(N)
POP_all = []
# print(POP_all)
# print(Asort(POP_all))
# 交叉概率
Pc = 0.8
# 变异概率
Pm = 0.1
# 进化过程
for i in range(iter_N):
POP_all = POP_all+POP
if np.random.random() < Pc: # 以Pc的概率进行交叉结合
POP = crossover(POP)
if np.random.random() < Pm: # 以Pm的概率进行变异
POP = mutation(POP)
POP_all = POP_all + POP
POP_end = Asort(POP_all)
POP = POP_end[0:N]
POP_all = []
# print(POP_all)
return POP
#调用进化函数,最后结果保存在result中。
result = implement()
result
#依次输出一下,查看结果如何。
for i in range(len(result)):
print(result[i].decode)
print(result[i].fitness)
#最后再绘制的函数曲线看一看。
import matplotlib.pyplot as plt
def func(x):
return x + 10 * np.sin(5 * x) + 7 * np.cos(4 * x)
x = np.linspace(-10, 10, 10000)
y = func(x)
scatter_x = np.array([ind.decode for ind in result])
scatter_y = np.array([ind.fitness for ind in result])
plt.plot(x, y)
plt.scatter(scatter_x, scatter_y, c='r')
plt.show()
最后结果: