在这个0-1背包的例子中,假设有12件物品,质量分别为2磅、5磅、18磅、3磅、2磅、5磅、10磅、4磅、11磅、7磅、14磅、6磅,价值分别为5元、10元、13元、4元、3元、11元、13元、10元、8元、16元、7元、4元,包的最大允许质量是46磅。
clear
clc
a = 0.95;
k = [5;10;13;4;3;11;13;10;8;16;7;4]; %价值
k = -k; %模拟退火算法是求解最小值,故取负值
d = [2;5;18;3;2;5;10;4;11;7;14;6]; %质量
restriction = 44;
num = 12;
sol_new = ones(1,num); %生成初始解
E_current = inf;
E_best = inf;
%E_current是当前解对应的目标函数值(即背包中物品总价值)
%E_new是新解的目标函数值
%E_best是最优解
sol_current = sol_new;
sol_best = sol_new;
t0 = 97;
tf = 3;
t = t0;
p = 1;
while t >= tf
for r = 1:100
%产生随机扰动
tmp = ceil(rand*num);
sol_new(1,tmp) = ~sol_new(1,tmp);
%检查是否满足约束
while 1
q = (sol_new * d <= restriction);
if ~q
p = ~p; %实现交错着逆转头尾的第一个1
tmp = find(sol_new == 1);
if p
sol_new(1,tmp(1)) = 0;
else
sol_new(1,tmp(end)) = 0;
end
else
break
end
end
%计算背包中的物品价值
E_new = sol_new * k;
if E_new < E_current
E_current = E_new;
sol_current = sol_new;
if E_new < E_best
E_best = E_new;
sol_best = sol_new;
end
else
if rand < exp( -(E_new - E_current) / t)
E_current = E_new;
sol_surrent = sol_new;
else
sol_new = sol_current;
end
end
end
t = t * a;
end
disp('最优解为:');
sol_best
disp('物品总价值等于:');
val = -E_best;
disp(val);
disp('背包中物品重量是:');
disp(sol_best * d);