0-1背包问题:
见代码:
function [f, IND] = knapsack01problem2(p,w,W)
% 输入: p:物品的利润 w:物品的重量 W:背包的容量
% 为了编程方便,假设W是大于等于2的正整数;w中每个元素都是大于等于1的正整数
m = length(p); % 物品个数
FF = zeros(m,W); % 初始化DP数组
% FF(i,j):前i件物品选择性的放入容量为j的背包中所能获得的最大利润
if w(1) <= W % 初始化第一行
FF(1,w(1):end) = p(1);
end
for i = 2:m % 初始化第一列
FF(i,1) = max([p(w(1:i) == 1),0]);
end
% i,j>1的情况
for i = 2:m
for j = 2:W
if w(i) > j % 第i件物品的重量w(i)比背包的容量j还要大
FF(i,j) = FF(i-1,j) ;
elseif w(i) == j % 第i件物品的重量w(i)等于背包的容量j
FF(i,j) = max(FF(i-1,j), p(i)); % 不放进去和放进去取较大的值
else % 第i件物品的重量w(i)小于背包的容量j
FF(i,j) = max(FF(i-1,j), p(i)+FF(i-1,j-w(i))); % 不放进去和放进去取较大的值
end
end
end
f = FF(m,W);
IND = []; % 选择的物品编号IND初始化为空
if f > 0 % 只要有利润,就可以利用FF来计算选择的物品编号IND
ww = W; % 初始化背包的剩余容量为整个背包的容量W
tmp = FF(:,ww); % 取出最后一列
while 1 % 不断循环下去,后面通过条件判断来退出循环
ind = find(tmp == max(tmp),1) ; % 找到装入背包的那个物品
ww = ww - w(ind); % 更新背包的剩余容量
IND = [IND,ind]; % 更新IND里面的元素
if ind > 1 && ww>0 % 只要不是第一个物品或者背包容量为空
tmp = FF(1:ind-1,ww); % 重新取出剩余容量的那一列(只保留前面的物品)
else
break % 跳出循环
end
end
IND = sort(IND); % 排序下,输出好看点
end
end
运输问题:
将上述问题转化为线性规划问题:
1.设xij为Ai运输至Bj的运货量,设p=[6 4 1 8 9 2 4 3 6]为与对应x的单价,因此目标函数为最小化P'*x
2.约束条件sum(X1j)=60,sum(X2j)=100···sum(i3)=50,共6个等式约束。
% 目标函数
f = [6 4 1 8 9 2 4 3 6]';
% 约束条件
m = 3;
n = 3;
Aeq1 = repmat( eye(m),1,n );
beq1 = [140 110 50]';
Aeq2 = kron( eye(m),[1 1 1] );
beq2 = [60 100 140]';
Aeq = [Aeq1;Aeq2];
beq = [beq1;beq2];
lb = zeros(m*n,1); % 下限
ub = 200*ones(m*n,1); % 上限
x = linprog(f,[],[],Aeq,beq,lb,ub)
y = f'*x