【Matlab】动态规划算法代码记录

简单记录一下学习Matlab过程中的代码。

一、01背包问题

参考资料:0-1背包问题

%01背包问题
clc;clear
thing=[1500;3000;2000;2000;100];thing_weight=[1;4;3;1;1];   %定义物品参数
bag=zeros(length(thing),4);[a,b]=size(bag);     %创建矩阵
for row=1:a
    for col=1:b
        if row == 1     %定义第一行数据
            bag(row,col) = thing(row);
        else            %其他行
            if col>thing_weight(row)   %口袋承重大于该行物品重
                bag(row,col) = max(bag(row-1,col),thing(row)+bag(row-1,col-thing_weight(row)));
            elseif col==thing_weight(row)
                bag(row,col) = max(thing(row),max(bag(:,col)));
            else                        %口袋承重小于该行物品重
                bag(row,col) = bag(row-1,col);
            end
        end
    end
end
disp(bag)

二、最少硬币个数问题

参考资料:清华学霸总结的动态规划4步曲,仅这篇动归够了

%%最少硬币组合
clc;clear
%%定义初始参数
coin=[2 5 7];
goal=27;
f=zeros(goal+2,1);
f(1)=inf;   %正无穷大
f(2)=0;
%%递归
for x=3:goal+2
    i=x-2;
    j=x-5;
    k=x-7;
    if i<0
        i=1;
    elseif i==0
        i=2;
    end
    if j<0
        j=1;
    elseif j==0
        j=2;
    end
    if k<0
        k=1;
    elseif k==0
        k=2;
    end
    f(x)=min([f(i)+1 f(j)+1 f(k)+1]);
end
n=f(end);   %符合goal的最少硬币数
disp(n)
%%查看硬币组合情况
%定义硬币库
a1=ones(n,1)*2;
a2=ones(n,1)*5;
a3=ones(n,1)*7;
A=[a1,a2,a3];
while true
    random_num = A(randperm(numel(A),n));   %从A中随机取n个元素
    if sum(random_num)==goal
        break
    end
end
disp(sort(random_num))

三、线性规划最优解

%水库动态规划
clc;clear
%每月来水量
input=[10 10 10 10 40 40 40 40 5 5 5 5];
%初始水量、最大水量、最小水量
w0=100;mx=130;mn=70;
%各月电价(水价)
f=[2;2;4;2;5;6;1;4;3;5;3;2]*-10;	% *-10是为了使输出结果更直观;负号是为了求最大值
%水库剩余水量应介于最大最小之间
b1=zeros(12,1);
b2=zeros(12,1);
p1=mx-w0;
p2=w0-mn;
for i=1:12
    p1=p1-input(i);
    p2=p2+input(i);
    b1(i)=p1;
    b2(i)=p2;
end
b=[b1;b2];
a1=tril(ones(12))*-1;	%下三角矩阵
a2=tril(ones(12));
a=[a1;a2];
[x,y]=linprog(f,a,b,[],[],ones(12,1)*5);	%求函数f最小值
disp(x)
disp(-y)
xplot=[1 2 3 4 5 6 7 8 9 10 11 12];
plot(xplot,f*-1,xplot,x,xplot,input)
xlabel('月份')
legend('电价','放水量','来水量')

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值