MATLAB代码
function [youJie,youZhi] = beiBao01(n,c,w,v)
%免疫算法解决01背包问题
%输入物品个数n,背包容量c,物品重量(列向量)w,物品价值(列向量)v
%输出得到的优解youJie,优值youZhi
%测试环境:MATLAB2018b
%% 随机生成01序列
geShu = 100; %样本个数
A = ones(n,geShu);
for i = 1:geShu
b = randperm(n,floor((n+1) * rand())); %随机生成几个数,经所在位置变为0
A(b,i) = 0;
end
%% 迭代
dieDai = 100;
for k = 1:dieDai
%% 对样本按一定规则筛选
A(:,sum(A .* w)>c) = []; %删去超出重量限制的解
len = size(A,2); %当前样本个数
qKY = qinHeKY(A,v); %计算抗体与抗原的亲和度
[qKY,index] = sort(qKY,'descend'); %降序排列
A = A(:,index);
qKY = qKY(:,1:floor(len/2)); %保留优质一半样本
A = A(:,1:floor(len/2));
len = size(A,2); %当前样本个数
qKK = zeros(len,len); %抗体与抗体的亲和度
for i = 1:len
for j = i+1:len
qKK(i,j) = qinHeKK(A(:,i),A(:,j),v);
end
end
qKK = qKK'+qKK;
%% 克隆变异/随机生成新样本
if mod(k,3) ~= 0 %每个几代随机生成一组新样本,避免陷入局部最优解
%% 克隆
yuZhi = 0.5; %设置一个阈值
qKK(qKK<yuZhi) = 0;
qKK(qKK>yuZhi) = 1;
T = sum(qKK);
T(T == 0) = 0.1;
p = qKY ./ T; %计算克隆的概率,与抗体与抗原的亲和度成正比、与抗体与抗体的亲和度成反比
p = p ./ sum(p); %归一化
index = randsample(1:len,geShu-len,true,p); %按概率随机生成一批样本,补足
A = [A,A(:,index)];
%% 交叉变异
bianYiP = 1 ./ qKY; %变异概率,与抗体与抗原的亲和度成反比
bianYiP = bianYiP ./ sum(bianYiP); %归一化
for j = 1:n
if randsample([0,1],1,true,[bianYiP(j),1-bianYiP(j)]) == 1 %进行变异(交换其中的排序)
p = randperm(geShu-len,2);
p = p + len;
temp=A(j,p(1));
A(j,p(1))=A(j,p(2));
A(j,p(2))=temp;
end
end
else %随机生成新样本
len = geShu - len;
B = ones(n,len);
for i = 1:len
b = randperm(n,floor((n+1) * rand()));
B(b,i) = 0;
end
A = [A,B];
end
end
youJie = A(:,1);
youZhi = sum(youJie .* v);
function [qKY] = qinHeKY(A,v)
%计算抗体与抗原的亲和度
%输入抗体集合(矩阵或向量)A,抗原v
%输出亲和度
%测试环境:MATLAB2018b
qKY = sum(A .* v); %这里亲和度用物品价值来表示
function [qKK] = qinHeKK(A1,A2,v)
%计算抗体与抗体的亲和度
%输入两个
%测试环境:MATLAB2018b
qA1 = qinHeKY(A1,v);
qA2 = qinHeKY(A2,v);
qaMax = max(qA1,qA2);
qaMin = min(qA1,qA2);
qKK = qaMin / qaMax;
%beiBao01Test.m
%调用算法求解
%运行环境:MATLAB2018b
clear
%n = 5;
%c = 10;
%w = [2 2 6 5 4]';
%v = [6 3 5 4 6]';
%[youJie,youZhi] = beiBao01(n,c,w,v);
%n = 5;
%c = 100;
%w = [77 22 29 50 99]';
%v = [92 22 87 46 90]';
%[youJie,youZhi] = beiBao01(n,c,w,v);
n = 8;
c = 200;
w = [79 58 86 11 28 62 15 68]';
v = [83 14 54 79 72 52 48 62]';
[youJie,youZhi] = beiBao01(n,c,w,v);
参考文献
免疫算法在背包问题中的应用www.wanfangdata.com.cn