贪心算法-MATLAB实现

贪心算法的基本原理

贪心算法是使所做的选择看起来都是当前最佳的,期望通过所做的局部最优选择来产生出一个全局最优解。

贪心算法的性质

  1. 贪心选择:在做贪心选择时,应满足可行性,即必须满足问题的约束条件。
  2. 局部最优:通过做一系列的选择来给出某一问题的最优解。对算法中的每一个决策点,做一个当时最佳的选择。
  3. 子结构结果:贪心算法所做的当前选择可能要依赖于已经做出的所有选择,但不依赖于有待于做出的选择或子问题的解。

例题

找零钱问题

题目:假设有7种硬币,面值分别为0.01元、0.02元、 0.05元、 0.1元、 0.2元、 0.5元、 1元。要找6.66元,问如何找钱才能使找出的硬币个数最少?
核心思想:每一次找钱都从零钱面值最大的算起,以确保每次找出的硬币数目最少
基本思路:

  1. 读取硬币和零钱的数值
  2. 从面值最大的硬币开始找起,逐步递减直到零钱值为零

MATLAB代码如下:

%贪心算法解决找零钱问题
% greedy algorithm(GA)贪心/贪婪算法
d=[0.01 0.02 0.05 0.5 0.1 0.2 1]%输入零钱面值,存入d数组中
%将数组d排序,使得其零钱面值为从小到大
value=sort(d)
a= input('请输入需要找的零钱数:')%a表示需要找的零钱数
i=length(value)%用length函数计算d数组的长度
while i>0
    if a>=value(i) %从面值最大的开始找,d[i]此时i=6 i的值是最大的,d[i]是最大的
        n=fix(a/value(i))%fix函数用于向下取整,n的含义是需要找的零钱个数
        a=round(a-n*value(i),2)%round保留两位小数
        X=sprintf('找了%d个%.2f元硬币',n,value(i))
        disp(X)
    end
    i=i-1
end

空瓶换酒问题

题目:小区便利店正在促销,用 3 个空酒瓶可以兑换一瓶新酒。你购入了 5 瓶酒。如果喝掉了酒瓶中的酒,那么酒瓶就会变成空的。请你计算最多能喝到多少瓶酒?
核心思想:每一次换酒都尽最大可能换最多的酒
基本思路:

  1. 设置交换规则并读取初值
  2. 记录剩余酒瓶的数量、喝到的酒的数量,当剩余酒瓶已经不能换酒时,停止循环

空瓶换酒问题示意图如下:
在这里插入图片描述MATLAB代码如下:

%贪心算法解决空瓶换酒问题
% greedy algorithm(GA)贪心/贪婪算法
a=1
while a==1
    %购入了 n 瓶酒
    n = input('你现在有几瓶酒?');
    %用 m 个空酒瓶可以兑换一瓶新酒
    m = input('几个酒瓶可以换一瓶酒?');
    if m<=1
        disp('输入错误 请重新输入')
        a=1
    else 
        a=0
    end
end
%初始化
count = n;  % 喝到酒的数目
e = n;  % 空瓶数目
%初始时,空瓶数量等于已有酒的数量,还未开始换酒
while fix(e / m) ~= 0 %fix函数向下取整,当手里有的空瓶数量一瓶酒的换不了了就结束循环
    bottle = fix(e / m);  % 利用当前空瓶最大限度地兑换酒,得到当前酒的数目
    count = count + bottle;  % 更新喝到酒的数目
    e = mod(e,m) + bottle; %更新空瓶数目:空瓶=兑换后剩余空瓶+兑换得到的酒瓶   mod函数:返回 e 除以 m 后的余数
end
X=sprintf('一共可以喝到%d瓶酒',count)
disp(X)

当酒的瓶盖也可以换酒时,则需考虑两个数量的变化,找到最大换酒数量,MATLAB代码如下:

%贪心算法解决空瓶换酒问题2.0% greedy algorithm(GA)贪心/贪婪算法
%初始化
clc;clear;
n=20%共有n瓶酒
m=2%用 m 个空酒瓶可以兑换一瓶新酒
q=3%用q个瓶盖可以换1瓶酒
count = n;  % 喝到酒的数目
e = n;  % 空瓶数目
f = n;  %瓶盖数目
while (fix(e / m) ~= 0 )||(fix(f/q)~=0)%fix函数向下取整,当手里有的空瓶数量一瓶酒的换不了了就结束循环
    if fix(e / m) ~= 0
        bottle_e = fix(e / m) % 利用当前空瓶最大限度地兑换酒,得到当前酒的数目
    end
    if fix(f / q) ~= 0
        bottle_f = fix(f / q)
        % 更新喝到酒的数
    end
    e = mod(e,m) + bottle_e+bottle_f; %更新空瓶数目:空瓶=兑换后剩余空瓶+兑换得到的酒瓶   mod函数:返回 e 除以 m 后的余数
    f = mod(f,q) + bottle_f+bottle_e; %更新瓶盖数目:瓶盖=兑换后剩余瓶盖+兑换得到的瓶盖
    count = count + bottle_e+bottle_f;
    bottle_e=0
    bottle_f=0
end
X=sprintf('最终喝到%d瓶酒',count)%最终喝到酒的瓶数
disp(X)

活动安排问题

题目:设有n个活动a1, a2…, an,每个活动都要求使用同一资源,而同一时间内只允许一个活动使用这一资源。已知活动ai,要求使用该资源的起始时间为si,结束时间为fi,且si<= fi。要求在a1, a2, …, an中选出最大的相容活动子集。
核心思想:按结束时间从早到晚安排活动,每次选择与已选出的活动相容的结束时间尽可能早的活动。以保证每次为资源留下尽可能多的时间以容纳其它活动。
基本思路:

  1. 读取活动的数据并排序
  2. 找出相容活动子集
  3. 输出结果

活动安排问题示意图如下:
在这里插入图片描述MATLAB代码如下:

%贪心算法解决活动安排问题
% greedy algorithm(GA)贪心/贪婪算法
s=[1 2 2 3 5 ]%s为活动开始时间
f=[5 6 8 9 10]%f为活动结束时间,并且s和f一一对应
n=5%n为活动的数量(1,5) (2,6) (2,8) (3,9) (5,10)
%排序,以活动最早结束的时间为标准,将活动排序,结束时间越早,越排在前面
[JL,Index]=sort(f)
f=JL
s=s(Index)
 for i =1:length(f)
     a(i)=[true];
 end
j = 1
for i =2:n
    %如果下一个活动的开始时间大于等于上个活动的结束时间,最关键的语句
    if s(i)>= f(j)
        a(i)= true
        j = i
    else
        a(i) = false
    end
end
  disp('安排的活动有')
for i =1:length(a)
    if a(i)
        X=sprintf('开始时间为%d,结束时间为%d的活动%d',s(i),f(i),i);
        disp(X)
    end
end

贪心算法的局限性

贪心法可以解决一些最优化问题,如:求最小生成树、求哈夫曼编码……对于其他问题,贪心法一般不能得到我们所要求的答案。一旦一个问题可以通过贪心法来解决,那么贪心法一般是解决这个问题的最好办法。 由于贪心法的高效性以及其所求得的答案比较接近最优结果,贪心法也可以用作辅助算法或者直接解决一些要求结果不特别精确的问题。在不同情况,选择最优的解,可能会导致辛普森悖论(Simpson’s Paradox),不一定出现最优的解。

  • 5
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
贪心算法MATLAB实现可以按照以下步骤进行: 1. 建立数学模型来描述问题。根据问题的要求和约束条件,使用MATLAB语言将问题转化为数学模型。 2. 把求解的问题分成若干个子问题。根据贪心算法的特点,将问题分解为一系列的子问题,每个子问题都是一个局部最优化问题。 3. 对每个子问题求解,得到子问题的局部最优解。使用MATLAB的优化函数或其他相关函数,对每个子问题进行求解,得到子问题的局部最优解。 4. 把子问题的解局部最优解合成原来问题的一个解。根据各个子问题的局部最优解,将它们合并起来,得到原问题的一个解。 需要注意的是,贪心算法并不保证能够得到问题的全局最优解,所以在使用贪心算法时需要进行充分的验证和测试,以确保得到的解是符合要求的。 参考文献: 贪心算法一般按如下步骤进行:建立数学模型来描述问题。把求解的问题分成若干个子问题。对每个子问题求解,得到子问题的局部最优解。把子问题的解局部最优解合成原来解问题的一个解。 贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。贪心算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心算法不要回溯。 要确定一个问题是否适合用贪心算法求解,必须证明每一步所作的贪心选择最终导致问题的整体最优解。证明的大致过程为:首先考察问题的一个整体最优解,并证明可修改这个最优解,使其以贪心选择开始,做了贪心选择后,原问题简化为规模更小的类似子问题。然后用数学归纳法证明通过每一步做贪心选择,最终可得到问题的整体最优解。应用实例。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【控制】贪心算法(GA,Greedy Algorithm)及 Matlab 实现](https://blog.csdn.net/weixin_36815313/article/details/120629061)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值