利用遺傳算法尋找函數f(x)=sin(10πx)/x x=[1,2]
轉載來源:https://blog.csdn.net/qq_33336017/article/details/79260688?tdsourcetag=s_pctim_aiomsg
解題思路
將自變量在給定范圍進行編碼,得到種群編碼,按照所選擇的適應度函數並通過遺傳算法中的選擇,交叉和變異對個體進行篩選和進化,使適應度值大的個體被保留,小的個體被淘汰,新的種群繼承上一代的信息,又優於下一代,這樣反復循環,最后得出最終結果
注:程序參考<<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()