西电遗传算法求最优解

遗传算法上机作业

在这里插入图片描述

一、算法流程

Step1(初始化) 确定种群规模N,交叉概率pc,变异概率pm和终止条件。 随机生成N个个体作为初始种群P(0),设种群代数t=0。

Step2(个体评价) 计算种群P(t)中每个个体的适应度值。

Step3(种群进化)

3.1 (选择父代) 运用选择算子从P(t)中选择出N/2对父代;

3.2 (交叉) 对选择的N/2对父代,依概率pc进行交叉,生成的子代个体记 为集合O1;

3.3 (变异) 对集合O1中的个体依概率pm进行变异,生成的子代个体记为 集合O2;

3.4 (选择子代) 从集合 中依据选择算子选出N个个体组成下一 代种群P(t+1);

Step4(终止检验) 如算法满足终止条件,则输出P(t+1)中具有最大适应 度值的个体作为最优解,终止算法。否则,令t=t+1,转入步骤3

def main():
    #变量范围
    decisionVariables = [[-3.0, 12.1], [4.1, 5.8]]
    #精度
    delta=0.0001
    #二进制编码长度
    length = getEncodeLength(decisionVariables,delta)
    #初始种群数
    N=200
    totallength=length[0]+length[1]
    #交叉概率
    pc=0.6
    #变异概率,注意是每个基因位变异的概率
    pm=0.01
    #保留精英数
    E=N//5
    # 最大进化代数
    maxgeneration = 200
    #保存每一代最大适应度对应个体的基因
    maxindividuals = []
    #保存每一代最大适应度
    maxfitness=[]
    #初始化种群
    population=getinitialPopulation(totallength,N)
    # print(population)
    for i in range(maxgeneration):
        #计算种群适应度
        populationfitness=getFitnessValue(population,decisionVariables,length)
        #利用轮盘赌选择选择N/2对父代进行交叉,生成交叉子代offspring
        selected_parents=selectNewPopulation(populationfitness,population,N)
        offspring=crossoverpopulation(selected_parents,pc)
        #对交叉生成的子代变异,生成交叉变异子代
        mutaoffspring=mutapopulation(offspring,pm)
        #选出父代和子代集合中最好的E个个体直接保留到下一代种群,然后,根据轮盘赌选择从父代和子代集合中选N-E个个体进入下一代种群
        totalpopulation=population+offspring+mutaoffspring
        totalpopulationfitness=getFitnessValue(totalpopulation,decisionVariables,length)
        #选出精英个体
        max_indices = get_max_indices(totalpopulationfitness, E)
        #精英种群
        Elites=[totalpopulation[i] for i in max_indices]
        #根据轮盘赌选择从父代和子代集合中选N-E个个体进入下一代种群
        temp=selectNewPopulation(totalpopulationfitness,totalpopulation,N-E)
        #生成下一个种群
        population=Elites+temp
        
        #记录每一代适应度最大值
        maxfitness.append(max(totalpopulationfitness))
        index=get_max_indices(totalpopulationfitness, 1)
        #保存每一代最大适应度对应个体的基因
        maxindividuals.append(totalpopulation[index[0]])

    
    maxval=np.max(maxfitness)
    index=get_max_indices(maxfitness, 1)
    maxindividual=maxindividuals[index[0]]

    print(maxval)
    print(maxindividual)
    print(decode(maxindividual,decisionVariables,length))
    
start_time = time.time()
main()
end_time = time.time()
runtime = end_time - start_time
print("程序运行时间: %.2f秒" % runtime)

在这里插入图片描述

二、具体实现

1.二进制编码

在这里插入图片描述

在这里插入图片描述

decisionVariables = [[-3.0, 12.1], [4.1, 5.8]]
#计算在变量范围decisionVariables下,精度为delta时变量的编码长度,本问题length=[18,15]
def getEncodeLength(decisionvariables, delta):
    # 将每个变量的编码长度放入数组
    lengths = []
    for decisionvar in decisionvariables:
        uper = decisionvar[1]
        low = decisionvar[0]
        
        # 计算变量范围的大小
        range_size = uper - low
        
        # 计算编码长度
        length = int(np.ceil(np.log2(range_size / delta + 1)))
        lengths.append(length)
    
    # 输出编码长度数组
    print("染色体长度:", lengths)
    
    return lengths

#解码函数,用解码公式
def decode(gene,decisionVariables,length):
    gene1=gene[0:length[0]]
    gene2=gene[length[0]:length[0]+length[1]]
    bin1=int(''.join(map(str, gene1)), 2)
    bin2=int(''.join(map(str, gene2)), 2)
    val1=decisionVariables[0][0]+(decisionVariables[0][1]-decisionVariables[0][0])*bin1/(2**length[0]-1)
    val2=decisionVariables[1][0]+(decisionVariables[1][1]-decisionVariables[1][0])*bin2/(2**length[1]-1)
    return val1,val2
#print(int(''.join(map(str, [1,1,0])), 2))
#print(decode([1,1, 1, 0,1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1,0, 0, 1, 0, 1, 1,0, 1,0],decisionVariables,length))

3.初始化种群

#初始化种群
def getinitialPopulation(totallength, populationSize):
    population=[]
    #种群大小为populationSize,totallength是基因总长度,本例为18+15=33
    for i in range(populationSize):
        individual=[]
        #每个基因位随机生成0或1
        for j in range(totallength):       
            individual.append(random.randint(0, 1))
        population.append(individual)
    return population
# print(getinitialPopulation(33,2))

4.适应度函数

#计算适应度函数
def fitnessFunction(a,b):
    return 21.5 + a * np.sin(4 * np.pi * a) + b * np.sin(20 * np.pi * b)

#计算种群适应度
def getFitnessValue(population,decisionVariables,length):
    fitness=[]
    for i in range(len(population)):
        x1,x2=decode(population[i],decisionVariables,length)
        # print(x1,x2)
        fitness.append(fitnessFunction(x1,x2))
    return fitness

5.轮盘赌选择函数

在这里插入图片描述

#通过轮盘赌选个体进入交叉池
def selectNewPopulation(populationfitnesss,population,n):
    total_fitness = sum(populationfitnesss)
	#首先,计算个体的适应度占总适应度的比值
    probabilities = [fitness / total_fitness for fitness in populationfitnesss]
    # 计算个体累计适应度
    cumulative_fitness = np.cumsum(probabilities)
    index=[]
    for i in range(n):
        #最后,随机产生10个[0,1]之间的实数,并选择对应的个体
        random_number = random.random()
        # print(random_number)
        for j in range(len(cumulative_fitness)):
            if(random_number<cumulative_fitness[j]):
                index.append(j)
                # print(j)
                break
    # print("index:",index)
    selected_parents=[]
    for i in range(len(index)):
        selected_parents.append(population[index[i]])
    return selected_parents

6.交叉函数

在这里插入图片描述

#交叉函数,根据交叉概率进行两点交叉,对选择的N/2对父代,依概率pc进行交叉
def crossover(parent1, parent2):
    random_numbers = [random.randint(0, 10) for _ in range(2)]
    min=np.min(random_numbers)
    max=np.max(random_numbers)
    child1 = parent1[:min] + parent2[min:max]+parent1[max:]
    child2 = parent2[:min] + parent1[min:max]+parent2[max:]
    return child1, child2

def crossoverpopulation(selected_parents,pc):
    offspring=[]
    for i in range(0,len(selected_parents),2):
        random_number = random.random()
        # print(random_number)
        if(random_number<pc):
            child1,child2=crossover(selected_parents[i],selected_parents[i+1])
            offspring.append(child1)
            offspring.append(child2)
    return offspring

7.变异函数

#变异函数,对集合O1中的个体依概率pm进行变异
def mutation(individual, pm):
    for i in range(len(individual)):
        random_number = random.random()
        if(random_number<pm):
            if(individual[i]==1):
                individual[i]=0
            else:
                individual[i]=1
    return individual

def mutapopulation(offspring,pm):
    mutaoffspring=[]
    for i in range(len(offspring)):
        mutaoffspring.append(mutation(offspring[i],pm))
    return mutaoffspring

8.工具函数

#以列表形式返回lst最大n个数的下标
def get_max_indices(lst, n):
    indices = sorted(range(len(lst)), key=lambda i: lst[i], reverse=True)[:n]
    return indices
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值