GA遗传算法

GA遗传算法

import numpy as np
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()

猜你喜欢

转载自blog.csdn.net/qq_42394743/article/details/80721204