Matlab 简单背包问题的遗传算法


遗传算法的基本认识

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


遗传算法主要掌握以下四点

编码和解码

要实现遗传算法首先需要弄清楚如何对求解问题进行编码和解码。对于函数优化问题,一般来说,有两种编码方式,一是实数编码,一是二进制编码,两者各有优缺点,二进制编码具有稳定性高、种群多样性大等优点,但是需要的存储空间大,需要解码过程并且难以理解;而实数编码直接用实数表示基因,容易理解并且不要解码过程,但是容易过早收敛,从而陷入局部最优。

交叉

1.单点交叉

指在个体编码串中只随机设置一个交叉点,将染色体分成两部分,子代染色体的左右两侧分别来自于父母染色体。

2.多点交叉

在个体编码串中随机设置了两个/多个交叉点,然后再以间隔交换的方式进行部分基因交换。

3.均匀交叉

两个配对个体的每个基因座上的基因都以相同的交叉概率进行交换,从而形成两个新个体。

变异

在交叉操作过后形成的新个体,有一定的概率会在某基因位上发生基因变异,与选择操作一样,这个操作是基于概率的,这个概率成为变异概率一般来说变异概率设置得很小。一般变异率设置为 P r ≤ 0.5   \\P_{r} \le 0.5\ Pr0.5 

选择

1.轮盘赌选择法

轮盘赌选择法是依据个体的适应度值计算每个个体在子代中出现的概率,并按照此概率随机选择个体构成子代种群。轮盘赌选择策略的出发点是适应度值越好的个体被选择的概率越大。

2.随机竞争选择法

每次随机选择两个个体比较适应度函数大小,取较优者直到满足种群个体数。

2.最佳保留选择法

先采用轮盘赌,然后父代中最优个体保留到子代,并淘汰最差的个体。


简单背包问题介绍

背包问题指这样一类问题,题意往往可以抽象成:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。(来自百度百科)

简单背包问题实例

至于杀鸡焉用牛刀?主要是因为该篇文章目的是加深对遗传算法实现的理解,让大家自己不看别人的代码也能自己编写实现出来。


matlab代码
close;clear;clc
%% 背包问题 运用遗传算法
weight = [2 2 6 5 4];
value = [6 3 5 4 6];

n = length(weight);
p1 = .95; %交叉概率
p2 = .15; %变异概率
max_diedai = 50; %最大迭代次数

%构建初始种群 
zhongqun_nums = 14;
max_weight = 10; % 背包最大承重
jiyin = zeros(1,n);

rand('state',sum(clock));
zhongqun1 = zeros(zhongqun_nums,n);
ave_value = zeros(1,max_diedai);
max_value = zeros(1,max_diedai);
for i = 1:zhongqun_nums
    jiyin = round(rand(1,n));
    while jiyin * weight' > max_weight
        jiyin = round(rand(1,n));
    end
    zhongqun1(i,:) = jiyin;
end
tic
for i = 1: max_diedai
    %交叉:单点
    zhongqun2 = zhongqun1;
    for k = 1: 2 : zhongqun_nums
        if rand < p1 %判断是否交叉
            pos = ceil(n*rand); %交叉位置
            temp1 = zhongqun2(k,:);
            temp2 = zhongqun2(k+1,:);
            temp = temp1(pos);
            temp1(pos) = temp2(pos);
            temp2(pos) = temp;
            if temp1 * weight' <= max_weight && temp2 * weight'  <= max_weight
                zhongqun2(k,:) = temp1;
                zhongqun2(k+1,:) = temp2;
            end
        end
    end
        %变异
        zhongqun3 = zhongqun1; %与交叉同等地位
        for k = 1:zhongqun_nums
            if rand < p2
                pos = ceil(n*rand);
                temp = zhongqun3(k,:);
                temp(pos) = ~temp(pos);
                if  temp * weight' <= max_weight
                    zhongqun3(k,:) = temp;
                end
            end
        end
        %选择 
        % 价值最大的前zhongqun_nums个
        zhongqun = [zhongqun1;zhongqun2;zhongqun3];
        temp_value = zhongqun*(value');
        [t,index] = sort(temp_value,'descend');
        ave_value(i) = sum(zhongqun(index(1:zhongqun_nums),:)*value')/zhongqun_nums;
        max_value(i) = zhongqun(index(1),:)*value';
        zhongqun1 = zhongqun(index(1:zhongqun_nums),:);
end
toc
disp('选择方式:')
disp(zhongqun(1,:))
disp('最大价值:')
disp(zhongqun(1,:)*value')
disp('最大重量:')
disp(zhongqun(1,:)*weight')

plot(ave_value,'-dr');
ylabel('平均价值');
xlabel('迭代周期');
figure
plot(max_value,'-ro');
ylabel('最大价值');
xlabel('迭代周期');

运行结果:

在这里插入图片描述

  • 10
    点赞
  • 5
    评论
  • 58
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 博客之星2020 设计师:CY__ 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值