GA遗传算法
import random
#染色体编码
def getEncodeLength(delta,boundList):
"""
delta:表示精度
boundList:每个变量上下界构成的数组
"""
#保存每个自变量的编码长度
encodeLength = []
for var in boundList:
lower,upper= var[0],var[1]
#求取编码长度:2^length <= (upper-lower)/delta < 2^(length+1)
def getBestLength(lower,upper):
index = 1
split = (upper-lower)/delta
while(2**index<=split):
index += 1
return index
result = getBestLength(lower,upper)
encodeLength.append(result)
return encodeLength
#生成初始种群
def createInitPopulation(encodeLength,size):
"""
encodeLength:每个变量编码长度构成的数组(getEncodeLength的返回结果)
size:种群的大小
"""
chromes = np.zeros((size,sum(encodeLength)))
for i in range(size):
#二进制编码
chromes[i:] = np.random.randint(0,2,size=sum(encodeLength),dtype=np.uint8)
return chromes
#将编码的二进制染色体解码为10进制的数据值
def decodeChrome(encodeLength,chromes,boundList,delta):
"""
encodeLength:每个变量编码长度构成的数组(getEncodeLength的返回结果)
chromes:二进制编码的染色体
boundList:每个变量上下界构成的数组
delta:精度
"""
size = chromes.shape[0]#初始样本量
variables = len(encodeLength)#自变量个数
decodeValues = np.zeros((size,variables))
for index,chrome in enumerate(chromes):
start = 0
#将变量值转为10进制数
for ind,length in enumerate(encodeLength):
power = length - 1
demical = 0
for i in range(start,start+length):
demical += chrome[i]*(2**power)
power -= 1
lower = boundList[ind][0]
upper = boundList[ind][1]
decodeValue = lower + demical*(upper-lower)/(2**length)
decodeValues[index,ind] = decodeValue
start = length
return decodeValues
#去解适应度及累积概率
def getFiness(decodeValues):
"""
decodeValues:解码后的数据(decodeChrome的返回结果)
"""
size,varaibles = decodeValues.shape
fitness = np.zeros((size,1))
for i in range(size):
fitness[i,0] = 21.5+decodeValues[i,0]*np.sin(4*np.pi*decodeValues[i,0])+decodeValues[i,1]*np.sin(20*np.pi*decodeValues[i,1])
probablity = fitness/np.sum(fitness)
cum_pro = np.cumsum(probablity)
return fitness,cum_pro
#选择下一代种群(模拟轮盘抽奖)
def selectNewPopulation(chromes,cum_probablity):
"""
chromes:二进制编码的染色体
cum_probablity:累积概率(getFiness的返回结果)
"""
m,n = chromes.shape
newPopulation = np.zeros((m,n))
randomNums = np.random.rand(m)
for i,p in enumerate(randomNums):
logic = cum_probablity>=p
index = np.where(logic==True)[0][0]
newPopulation[i,:]=chromes[index,:]
return newPopulation
#实现染色体交叉
def cross(newPopulation,p):
"""
newPopulation:选取的下一代种群
p:交叉率
"""
m,n = newPopulation.shape
numbers = int(m*p)
#保证待交叉的染色体数为偶数
if numbers%2 != 0:
numbers += 1
update = np.zeros((m,n))
index = random.sample(range(m),numbers)
for i in range(m):
if i not in index:
update[i:] = newPopulation[i,:]
while(len(index)>0):
a = index.pop()
b = index.pop()
#随机选择某位点进行交叉
crossPoint = random.sample(range(1,n),1)[0]
update[a,0:crossPoint] = newPopulation[a,0:crossPoint]
update[a,crossPoint:] = newPopulation[b,crossPoint:]
update[b,0:crossPoint] = newPopulation[b,0:crossPoint]
update[b,crossPoint:] = newPopulation[a,crossPoint:]
return update
#实现染色体变异
def mutation(population,p):
"""
p:变异率
"""
tmp = population.copy()
m,n = population.shape
geneNums = int(m*n*p)
#染色体变异的位置
mutationPosition = random.sample(range(0,m*n),geneNums)
for position in mutationPosition:
#确定变异位置在数组中的下标
row,col= position // n,position % n
#实现变异:1-0 / 0-1
if tmp[row,col] == 0:
tmp[row,col] = 1
else:
tmp[row,col] = 0
return tmp
#主函数
def main():
optimalX = []
optimalValues = []
#最大迭代次数
iter_times = 500
delta = 0.001
boundList = [(-1,2.8),(4.5,6.4)]
encodeLength = getEncodeLength(delta,boundList)
for time in range(iter_times):
#对初始种群进行交叉变异
chromes = createInitPopulation(encodeLength,10)
decodedValues = decodeChrome(encodeLength,chromes,boundList,delta)
fitness,cumProbablity = getFiness(decodedValues)
population = selectNewPopulation(chromes,cumProbablity)
crossPopulation = cross(population,0.8)
mutationPopulation = mutation(crossPopulation,0.01)
#选你则下一代种群
finalSample = decodeChrome(encodeLength,mutationPopulation,boundList,delta)
final_fitness,final_proba = getFiness(finalSample)
optimalValues.append(np.max(final_fitness))
index = np.argmax(final_fitness)
optimalX.append(finalSample[index,:])
optimalY = np.max(optimalValues)
bestIndex = np.argmax(optimalValues)
optimal = optimalX[bestIndex]
print('最优解:x1={},x2={}'.format(optimal[0],optimal[1]))
print('最优目标值:{}'.format(optimalY))
if __name__ == '__main__':
main()