遗传算法求函数最小值
利用遗传算法寻找函数f(x)=sin(10πx)/x x=[1,2]
解题思路
将自变量在给定范围进行编码,得到种群编码,按照所选择的适应度函数并通过遗传算法中的选择,交叉和变异对个体进行筛选和进化,使适应度值大的个体被保留,小的个体被淘汰,新的种群继承上一代的信息,又优于下一代,这样反复循环,最后得出最终结果
注:程序参考<<MATLAB智能智能算法30个案例>>, 依照matlab程序,用python进行了重写
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
from pylab import *
import random
import math
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
#定义遗传算法参数
pop_size=40
generation=20
length=30
pc=0.65
pm=0.01
#编码
def genEncoding(pop_size,length):
pop=[[]]
for i in range(pop_size):
temp=[]
for j in range(length):
temp.append(random.randint(0,1))
pop.append(temp)
return pop[1:]
#解码
def genDecoding(pop,length):
temp=[]
for i in range(len(pop)):
t=0
for j in range(length):
t+=pop[i][j]*math.pow(2,j)
temp.append(t)
return temp
#计算目标值
def calobjValue(pop,length,lb,ub):
temp1=[]
obj_value=[]
x_value=[]
temp1=genDecoding(pop,length)
for i in range(len(temp1)):
x=lb+(ub-lb)*temp1[i]/((math.pow(2,length))-1)
x_value.append(x)
obj_value.append(np.sin(10*pi*x)/x)
return obj_value
#计算适应度
def fitness(pop,length,lb,ub):
obj_value=[]
fitness_value=[]
obj_value=calobjValue(pop,length,lb,ub)
for i in range(len(obj_value)):
fitness_value.append(obj_value[i]-1)
fitness_value=list(map(abs,fitness_value))
return fitness_value
#累积适应度
def cumsum(newfitness_value):
accumulation_value=[]
t=0
for i in range(len(newfitness_value)):
t+=newfitness_value[i]
accumulation_value.append(t)
return accumulation_value
#选择函数
def selection(pop,fitness_value):
newfitness_value=[]
accumulation_value=[]
total_fit=np.sum(fitness_value)
for i in range(len(fitness_value)):
newfitness_value.append(fitness_value[i]/total_fit)
accumulation_value=cumsum(newfitness_value)
ms=[]
for i in range(len(pop)):
ms.append(random.random())
newin=0
newpop=[]
for i in range(len(ms)):
j=0
for j in range(len(accumulation_value)):
if ms[i]<accumulation_value[j]:
t=pop[j]
newpop.append(t)
break
return newpop
#交叉函数
def crossover(pop,fitness_value,pc):
newpop=[]
newpop=selection(pop,fitness_value)
for i in range(len(newpop)-1):
if random.random()<pc:
temp1=[]
temp2=[]
temp1=newpop[i][3:15]
temp2=newpop[i+1][3:15]
newpop[i][3:15]=temp2
newpop[i+1][3:15]=temp1
return newpop
def mutation(pop,fitness_value,pc,pm,length):
newpop=[]
newpop=crossover(pop,fitness_value,pc)
for i in range(len(newpop)):
if random.random()<pm:
m1=random.randint(0,length-1)
m2=random.randint(0,length-1)
m3=random.randint(0,length-1)
if newpop[i][m1]==1:
newpop[i][m1]=0
else:
newpop[i][m1]=1
if newpop[i][m2]==1:
newpop[i][m2]=0
else:
newpop[i][m2]=1
if newpop[i][m3]==1:
newpop[i][m3]=0
else:
newpop[i][m3]=1
i=0
return newpop
if __name__ =='__main__':
#画出函数图
plt.figure(1)
lb=1
ub=2
x=np.arange(lb,ub,0.01)
y=sin(10*pi*x)/x
plt.plot(x,y)
plt.xlabel("自变量x")
plt.ylabel("自变量y")
plt.title('sin(10*pi*x)/x')
pop=genEncoding(pop_size,length)
obj_value=calobjValue(pop,length,lb,ub)
fitness_value=fitness(pop,length,lb,ub)
gen=0
x_value=[]
best_x=[]
best_individual=[]
Generation=[]
while gen<generation:
newpop=mutation(pop,fitness_value,pc,pm,length)
temp=genDecoding(newpop,length)
for i in range(len(temp)):
x=lb+(ub-lb)*temp[i]/((math.pow(2,length))-1)
x_value.append(x)
obj_value=calobjValue(newpop,length,lb,ub)
k=0
j=0
for i in range(len(obj_value)):
if k>obj_value[i]:
k=obj_value[i]
j=i
best_individual.append(k)
best_x.append(x_value[j])
fitness_value=fitness(newpop,length,lb,ub)
Generation.append(gen)
gen=gen+1
k=0
j=0
for i in range(len(best_individual)):
if k>best_individual[i]:
k=best_individual[i]
j=i
print(best_individual[j])
print(best_x[j])
best_individual.sort(reverse=True)
plt.figure(2)
plt.plot(Generation,best_individual)
plt.xlabel("遗传代数")
plt.ylabel("解的变化")
plt.title("进化过程")
plt.show()