Matlab遗传算法求函数最大值

用遗传算法求目标函数的最大值

主函数函数main.m

global Bitlength%定义3个全局变量
global boundsbegin
global boundsend
boundsbegin=-2;
boundsend=2;
precision=0.0001;%运算精确度
Bitlength=ceil(log2((boundsend-boundsbegin)'./precision));%染色体长度
popsize=50;%初始种群大小
Generationmax=12;%最大进化代数
pcrossover=0.90;%交叉概率
pmutation=0.09;%变异概率
population=round(rand(popsize,Bitlength));%随机生产初始化种群
[Fitvalue,cumsump]=fitness(population); %调用子函数1算个体适应度和选择累积概率
Generation=1;
while Generation<Generationmax+1%总共进化12代
    for j=1:2:popsize%每一次生成2个个体,经过25次循环生产一个新种群,完成一代进化
        seln=selection(population,cumsump);%调用子函数2选择操作,返回选中的2个个体的序号
        scro=crossover(population,seln,pcrossover);%调用子函数3交叉操作,返回2条染色体
        scnew(j,:)=scro(1,:);%存储交叉操作返回的染色体
        scnew(j+1,:)=scro(2,:);
        smnew(j,:)=mutation(scnew(j,:),pmutation);%调用子函数4对交叉操作返回的染色体变异
        smnew(j+1,:)=mutation(scnew(j+1,:),pmutation);    
    end
    population=smnew;%更新种群
    [Fitvalue,cumsump]=fitness(population);%调用子函数1计算新种群的适应度
    [fmax,nmax]=max(Fitvalue);%记录最佳适应度和其染色序号
    fmean=mean(Fitvalue);
    ymax(Generation)=fmax;%记录当代最佳适应度
    ymean(Generation)=fmean;%记录当代平均适应度
    x=transform2to10(population(nmax,:));%调用子函数6转化为10进制数
    xx=boundsbegin+x*(boundsend-boundsbegin)/(power(boundsend,Bitlength)-1);%将x整合到[-2,2]区间中
    xmax(Generation)=xx;%保存整合后最佳染色体10进制的值
    Generation=Generation+1;%依次循环进化12代,得到最佳种群个体
end
Generation=Generation-1
Bestpopulation=xx%最佳种群个体,即x的值
Targetmax=targetfun(xx)%调用子函数7要求的函数的最大值

子函数1:计算适应度和累积选择率fitness.m

function [Fitvalue,cumsump]=fitness(population)
global Bitlength
global boundsbegin
global boundsend
popsize=size(population,1);%总共计算多少个个体
for i=1:popsize
    x=transform2to10(population(i,:));%调用子函数6转化为10进制数
    xx=boundsbegin+x*(boundsend-boundsbegin)/(power((boundsend),Bitlength)-1);
    Fitvalue(i)=targetfun(xx);
end
Fitvalue=Fitvalue'+230;
fsum=sum(Fitvalue);
everypopulation=Fitvalue/fsum;
cumsump(1)=everypopulation(1);
for i=2:popsize
    cumsump(i)=cumsump(i-1)+everypopulation(i);
end
cumsump=cumsump';

子函数2:选择操作函数selection.m

function seln=selection(population,cumsump)
%子函数选择操作,从种群中随机选择2个个体
for i=1:2
    r=rand;
    j=1;
    prand=cumsump-r;
    while prand(j)<0
        j=j+1;
    end
    seln(i)=j;%选择个体的序号
end

子函数3:交叉操作函数crossover.m

function scro=crossover(population,seln,pc)
global Bitlength
pcc=IfcroORmut(pc);%调用子函数5判断是否进行交叉
if pcc==1%进行交叉
    c=round(rand*(Bitlength-2))+1;%在[1,Bitlength-1]范围内随机产生一个交叉位
    scro(1,:)=[population(seln(1),1:c) population(seln(2),c+1:Bitlength)];
    scro(2,:)=[population(seln(2),1:c) population(seln(1),c+1:Bitlength)];
else%不交叉,返回原值
    scro(1,:)=population(seln(1),:);
    scro(2,:)=population(seln(2),:);
end

子函数4:变异操作mutation.m

function smnew=mutation(scnew,pmutation)
global Bitlength
smnew=scnew;
paa=IfcroORmut(pmutation);调用子函数5,判断是否进行变异
if paa==1
    v=round(rand*(Bitlength-1))+1;%在[1,Bitlength]中选择一个变异位
    smnew(v)=abs(scnew(v)-1);%将smnew中第V个位置变异 
end

子函数5:判断是否进行交叉或者变异IfcroORmut.m

function pcc=IfcroORmut(mutORcro)
judge(1:100)=0;
L=round(100*mutORcro);
judge(1:L)=1;
n=round(rand*99)+1;
pcc=judge(n);

子函数6:二进制转化为十进制transform2to10.m

function x=transform2to10(Population)
global Bitlength
x=Population(Bitlength);
for i=1:Bitlength-1
    x=x+Population(Bitlength-i)*power(2,i);
end

子函数7:目标函数即为适应度函数targetfun.m

function y=targetfun(x)
%适应度函数,即原函数
y=200*exp(-0.05*x).*sin(x);

运行结果:
运行结果如图
当进化了12代后,x约等于1.5时取到最大值185。

遗传算法是一种基于自然界选择过程(如繁殖、变异和自然淘汰)的优化搜索技术,它能够应用于寻找函数最大值。在解决最大化问题时,通常我们构建一个群体,其中每个个体代表一组潜在解决方案,即一系列参数设置。 以下是使用遗传算法求解最大值的一般步骤: ### 1. 初始化群体 首先创建一个包含若干随机个体(解决方案)的初始种群。每个个体由一组参数组成,这些参数对应于特定问题的变量。例如,在寻找函数`f(x)`最大值的情况下,每个性体可以表示为一个x的数值列表。 ### 2. 定义适应度函数 适应度函数用于评估群体内各个个体的好坏程度。对于最大化问题,适应度函数通常是目标函数值的直接反向,也就是说,如果目标是最小化某个成本函数,则适应度函数计算该成本函数的值,并将其作为衡量个体质量的标准。对于寻找最大值的问题,适应度函数直接就是目标函数。 ### 3. 进行选择操作 根据适应度函数对个体进行排序,然后选择出一部分“优秀”的个体进入下一轮。常见的选择策略有轮盘赌选择、锦标赛选择等。这些方法倾向于让“好”个体(适应度高的个体)有更多的机会成为下一代的一部分。 ### 4. 应用交叉操作 交叉操作(也称为重组或交配)是指从两个父代个体中生成新的后代的过程。通过随机选取两个个体的部分基因片段交换位置,产生两个新的个体,这个过程有助于探索更广阔的解决方案空间。 ### 5. 进行变异操作 变异操作是引入随机变化到个体的一个或多个基因上,以增加群体的多样性。这一步骤防止了过早收敛于局部最优解。 ### 6. 更新种群并迭代 将新产生的个体替换掉原来的种群中的相应个体,形成新的一代。重复步骤3至5直到满足某种停止条件,比如达到预设的迭代次数,适应度函数达到满意的值,或者群体内的个体适应度不再显著提高。 ### 实现示例 在Python中,使用`DEAP`库可以方便地实现遗传算法。下面是一个简化的示例,假设我们想要找到函数`f(x) = -x^2 + 10x`的最大值: ```python import random from deap import base, creator, tools # 目标函数 def evaluate(individual): x = individual return -(x**2 + 10*x), # 设置环境 creator.create("FitnessMax", base.Fitness, weights=(1.0,)) creator.create("Individual", list, fitness=creator.FitnessMax) toolbox = base.Toolbox() toolbox.register("attr_float", random.uniform, -10, 10) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=1) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("evaluate", evaluate) toolbox.register("mate", tools.cxTwoPoint) toolbox.register("mutate", tools.mutUniformFloat, low=-10, up=10, indpb=0.1) toolbox.register("select", tools.selTournament, tournsize=3) pop = toolbox.population(n=50) fitnesses = list(map(toolbox.evaluate, pop)) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit NGEN = 50 for gen in range(NGEN): offspring = toolbox.select(pop, len(pop)) # selection offspring = list(map(toolbox.clone, offspring)) for child1, child2 in zip(offspring[::2], offspring[1::2]): if random.random() < 0.5: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values for mutant in offspring: if random.random() < 0.2: toolbox.mutate(mutant) del mutant.fitness.values invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit pop[:] = offspring best_ind = tools.selBest(pop, 1) print("Best solution is %s with a fitness of %s" % (best_ind, best_ind.fitness.values)) ``` 以上脚本演示了一个简单的遗传算法实例,用于找到给定范围内的`x`使得函数`f(x) = -x^2 + 10x`最大化的`x`值。在这个例子中,我们通过调整参数(如群体大小、交叉率、变异概率以及迭代次数)来优化结果。 ---
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔法战胜魔法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值