遗传算法与matlab实现 Genetic Algorithm

遗传算法与matlab实现

介绍

遗传算法(Genetic Algorithm, GA)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。

其主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;具有内在的隐并行性和更好的全局寻优能力;采用概率化的寻优方法,不需要确定的规则就能自动获取和指导优化的搜索空间,自适应地调整搜索方向。

流程图解

img

(摘自百度百科)

编码

常用的编码方式有二进制编码法、浮点编码法、符号编码法。

这里采用的是二进制编码法。规定染色体长度为17,则一个个体的编码示例如下:

00001111000011110

初始化

首先定义种群大小、染色体长度等基本量:

elitism = true;             % 选择精英操作
population_size = 100;      % 种群大小
chromosome_size = 17;       % 染色体长度
generation_size = 200;      % 最大迭代次数
cross_rate = 0.6;           % 交叉概率
mutate_rate = 0.01;         % 变异概率

对种群中的每一个个体进行初始化,这里随机产生0与1对种群population数组进行幅值。

function init(population_size, chromosome_size)
global population;
for i=1:population_size
    for j=1:chromosome_size
        % 给population的i行j列赋值
        population(i,j) = round(rand);  % rand产生(0,1)之间的随机数,round()是四舍五入函数
    end
end

迭代过程

迭代次数已在初始化中给定 generation_size = 200(即流程图中的GEN)。

for G=1:generation_size   
    fitness(population_size, chromosome_size);              % 计算适应度 
    rank(population_size, chromosome_size);                 % 对个体按适应度大小进行排序
    selection(population_size, chromosome_size, elitism);   % 选择操作
    crossover(population_size, chromosome_size, cross_rate);% 交叉操作
    mutation(population_size, chromosome_size, mutate_rate);% 变异操作
end

计算适应度

进化论中的适应度,是表示某一个体对环境的适应能力,也表示该个体繁殖后代的能力。遗传算法的适应度函数也叫评价函数,是用来判断群体中的个体的优劣程度的指标,它是根据所求问题的目标函数来进行评估的。

在每次计算前将初始化为0,注意这里使用浮点数进行初始化:

for i=1:population_size
    fitness_value(i) = 0.;    
end

计算适应度的函数假定为 f(x) = -x-10sin(5x)-7cos(4x)

遍历每一个个体的每一个基因,首先将二进制转换为十进制,再将十进制数映射到自定义的变量区间里,比如这此程序中,就将0 - (2^17 - 1) 映射到了区间 (0,9) 中。

最后根据区间映射的值计算适应度。

在使用中,如果没有需求,其实可以不必映射到特定区间,修改适应度函数后直接使用十进制数计算适应度即可。

for i=1:population_size
    for j=1:chromosome_size
        if population(i,j) == 1
            fitness_value(i) = fitness_value(i)+2^(j-1);    % population[i]染色体串和实际的自变量xi二进制串顺序是相反的
        end        
    end
    fitness_value(i) = lower_bound + fitness_value(i)*(upper_bound-lower_bound)/(2^chromosome_size-1);  % 自变量xi二进制转十进制
    fitness_value(i) = fitness_value(i) + 10*sin(5*fitness_value(i)) + 7*cos(4*fitness_value(i));  % 计算自变量xi的适应度函数值
end

按适应度进行个体排序

在每一次计算完适应度之后都要挑选出适应度最高的个体信息。

遍历种群,使用冒泡排序法,使得population(i)的适应度随i递增而递增,population(1)最小,population(population_size)最大。

for i=1:population_size
    min_index = i;
    for j = i+1:population_size
        if fitness_value(j) < fitness_value(min_index);
            min_index = j;
        end
    end
    
    if min_index ~= i
        % 交换 fitness_value(i) 和 fitness_value(min_index) 的值
        temp = fitness_value(i);
        fitness_value(i) = fitness_value(min_index);
        fitness_value(min_index) = temp;
        % 此时 fitness_value(i) 的适应度在[i,population_size]上最小
        
        % 交换 population(i) 和 population(min_index) 的染色体串
        for k = 1:chromosome_size
            temp_chromosome(k) = population(i,k);
            population(i,k) = population(min_index,k);
            population(min_index,k) = temp_chromosome(k);
        end
    end
end

计算前i个个体的适应度之和fitness_sum(i),在后续选择操作中会用到。

for i=1:population_size
    if i==1
        fitness_sum(i) = fitness_sum(i) + fitness_value(i);    
    else
        fitness_sum(i) = fitness_sum(i-1) + fitness_value(i);
    end
end

保存最佳个体的信息

% fitness_average(G) = 第G次迭代 个体的平均适应度
fitness_average(G) = fitness_sum(population_size)/population_size;

% 更新最大适应度和对应的迭代次数,保存最佳个体(最佳个体的适应度最大)
if fitness_value(population_size) > best_fitness
    best_fitness = fitness_value(population_size);
    best_generation = G;
    for j=1:chromosome_size
        best_individual(j) = population(population_size,j);
    end
end

选择

从群体中选择优胜的个体,淘汰劣质个体的操作叫选择。选择的目的是把优化的个体(或解)直接遗传到下一代或通过配对交叉产生新的个体再遗传到下一代。

遗传算法中的选择操作就是用来确定如何从父代群体中按某种方法选取那些个体,以便遗传到下一代群体。选择方法有很多,本程序中策略如下:

遍历种群。每次遍历中:

首先生成一个随机数,在[0,总适应度]之间。在适应度排序中,我们已经计算出了计算前i个个体的适应度之和fitness_sum(i),接下来就可以用排中法选择适应度之和最接近次随机数的个体的位置。

取得此个体位置后,根据此个体的基因产生一个新的个体。

在遍历结束后,用population_new更新所有个体。选择操作完成。

通过这种选择操作,每次生成的随机数在[0,总适应度]之间,而population(i)的适应度随i递增而递增,因此用排中法选择的population(idx)总体数值会靠近中间值,适应度低的个体会被淘汰。

在程序中还加入了精英选择的选项,如果进行精英选择,则每次选择时都会将最优的个体保留。

for i=1:population_size
    r = rand * fitness_sum(population_size);  % 生成一个随机数,在[0,总适应度]之间
    first = 1;
    last = population_size;
    mid = round((last+first)/2);
    idx = -1;
    
    % 排中法选择个体
    while (first <= last) && (idx == -1) 
        if r > fitness_sum(mid)
            first = mid;
        elseif r < fitness_sum(mid)
            last = mid;     
        else
            idx = mid;
            break;
        end
        mid = round((last+first)/2);
        if (last - first) == 1
            idx = last;
            break;
        end
    end
   
   % 产生新一代个体
   for j=1:chromosome_size
        population_new(i,j) = population(idx,j);
   end
end

% 是否精英选择
if elitism
    p = population_size-1;
else
    p = population_size;
end

for i=1:p
   for j=1:chromosome_size
       % 如果精英选择,将population中前population_size-1个个体更新,最后一个最优个体保留
       population(i,j) = population_new(i,j);
   end
end

交叉

在自然界生物进化过程中起核心作用的是生物遗传基因的重组。同样,遗传算法中起核心作用的是遗传操作的交叉算子。遗传算法的交叉操作,是指对两个相互配对的染色体按某种方式相互交换其部分基因,从而形成两个新的个体。通过交叉,遗传算法的搜索能力得以飞跃提高。

给定交叉概率cross_rate,以步长为2遍历种群,如果随机生成的(0,1)的数小于交叉概率,则对相邻的个体进行交叉操作。

交叉算子的选择有很多,此程序选择较简单的做法,具体操作是:在染色体长度范围内随机选择一个位置cross_position,交换相邻个体此位置后所有的基因片段。

for i=1:2:population_size
    % rand<交叉概率,对两个个体的染色体串进行交叉操作
    if(rand < cross_rate)
        cross_position = round(rand * chromosome_size);
        if (cross_position == 0 || cross_position == 1)
            continue;
        end
        % 对 cross_position及之后的二进制串进行交换
        for j=cross_position:chromosome_size
            temp = population(i,j);
            population(i,j) = population(i+1,j);
            population(i+1,j) = temp;
        end
    end
end

变异

遗传算法中的变异运算,是指将个体染色体编码串中的某些基因座上的基因值用该基因座上的其它等位基因来替换,从而形成新的个体。

随机选择变异位置,对该位置的基因进行取反。

for i=1:population_size
    if rand < mutate_rate
        mutate_position = round(rand*chromosome_size);  % 变异位置
        if mutate_position == 0
            % 若变异位置为0,不变异
            continue;
        end
        population(i,mutate_position) = 1 - population(i, mutate_position);
    end
end

结束

主循环结束后,即可获得最优个体和适应度等结果,输出即可。

disp 最优个体:
best_individual
disp 最优适应度:
best_fitness
disp 最优个体对应自变量值:
x
disp 达到最优结果的迭代次数:
iterations

matlab源代码见我个人空间或前往链接

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值