python算法之贪心算法

前言

贪心算法在解决问题时总想着用当前看来最好的方法来实现。其不从整体最优上考虑问题,仅考虑某种意义上的局部最优来求解问题。贪心算法的有点是:当面对范围比较大的问题时,能产生整体最优解或整体最优解的近似值。

贪心算法的存在问题

  1. 不能保证最后的解是最优的。
  2. 不能用来求最大解或者最小解问题。
  3. 只能求满足某种约束条件的可行解的范围。

贪心算法的基本思路

  1. 建立数学模型来描述问题。
  2. 把求解的问题分解成若干个子问题。
  3. 对每一子问题求解,得到子问题的局部最优解。
  4. 把子问题的局部最优解合并成原来问题的一个解。

实现算法基本过程

  1. 从问题的某一初始解出发。
  2. while能向给定总目标前进一步。
  3. 求出可行解的一个解元素。
  4. 由所有解元素组合成问题的一个可行解。

案例

解决“找零”问题

假设只有1分,2分,5分,1角,2角,5角,1元面值的硬币。在超市结账找零时,收银员希望将最少的硬币数找给顾客,那么给定找零的零钱数目,如何求得最小的硬币数 ?

def look():
    d=[0.01,0.02,0.05,0.1,0.2,0.5,1.0]  #存储每种硬币的面值
    d_num=[]    #存储每种硬币的数量
    s=0     #拥有零钱的总钱
    temp=input('请输入每种零钱的数量(以空格为区分)')
    d_num0=temp.split(' ')
    for i in range(0,len(d_num0)):
        d_num.append(int(d_num0[i]))
        s+=d[i]*d_num[i]    #计算收银员需要多少钱
        
    sum=float(input('请输入需要找的零钱'))
    if sum >s:  #待找零钱数大于已有钱数
        print("数据有误")
        return 0
    s=s-sum     #柜台剩余钱数
    #要想用的硬币数量最少,需要利用所有面值最大的硬币,因此从数组的最大面值开始遍历
    i=len(d)-1     
    while i>=0:
        if sum >=d[i]:
            n=int(sum/d[i])
            if n >=d_num[i]:    #如果现有该面值硬币数小于所需要的该面值硬币数
                n=d_num[i]  #更新n
            sum-=n*d[i] #贪心算法的关键步骤,令sum动态改变
            print("用了%d个%f枚硬币"%(n,d[i]))
        i-=1
if __name__ == '__main__':
    look()
    
解决“汽车加油”问题

一辆汽车加满油后可行驶n千米,旅途中有若干个加油站,指出应在哪些加油站停靠加油,使沿途加油次数最少。对于给定的n(<=5000)千米和(k<1000)个加油站位置,计算最少加油次数?

def greedy():
    n=100
    k=5
    num=0       #加油次数
    d=[50,80,39,60,40,32]   #表示加油站之间的距离
    for i in range(k):
        if d[i]>n:
            print("没有解决方案")
    i,s=0,0     #s表示距离,进行迭代
    while i<=k:
        s +=d[i]
        if s>=n:
            #当局部和大于n时,则将局部和更新为当前距离
            s=d[i]
            #贪心算法意在让每一次加满油后尽可能跑的更远
            num+=1
        i+=1
    print(num)
if __name__ == '__main__':
    greedy()

总结

1.贪心算法的核心:不从整体最优上考虑问题,仅考虑某种意义上的局部最优来求解问题。
2.建立数学模型来描述问题。

扫描下方二维码,关注公众号,即可免费领取学习资源,每周都有更新!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值