python贪心算法几个经典例子_Python笔试——贪心算法

贪心算法

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

基本思路

思想

贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解。每一步只考虑一个数据,他的选取应该满足局部优化的条件。若下一个数据和部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止 。

步骤

遍历初始集合X中的备选元素

利用贪心策略在X中确定一个元素,并将其加入到可行解S中

得到可行解S

1540153-20200809201916386-1396700165.png

P即为贪心策略,用来选择符合条件的元素。

例子——硬币找零

假设某国硬币面值有1,5,10,25,100元五种面额,若店员为顾客找零时,需要给顾客找零a=36元,求硬币数最少的情况。

1540153-20200809202908581-1438945404.png

这里我们的贪心策略为:

先找到最接近a的值,然后对a进行更新,然后进行循环。

代码实现

defshortNum(a):

coins= [1,5,10,25,100]

out=[]

coins= coins[::-1]for i incoins:

num= a//i

out=out+[i,]*num

a= a-num*iif a<=0:break

returnout

a= 36

print(shortNum(a))

例子——任务规划

问题描述:

输入为任务集合X= [r1,r2,r3,...,rn],每个任务ri,都对应着一个起始时间ai与结束时间bi

要求输出为最多的相容的任务集。

1540153-20200809205444410-2014902989.png

如上图,r1与r2相容,r3与r1和r2都不相容。

那么这里的贪心策略我们可以设为:

先将结束时间最短的任务加入到S中,

再从剩下的任务的任务中选择结束时间最短的,且判断与S集合中的任务是否相容

若不相容,则换下一个时间最短的任务,并进行比较

循环,直至X为空。

代码实现

#任务规划

from collections importOrderedDict

task=OrderedDict()

task['r1'] = [0,4]

task['r2'] = [5,8]

task['r3'] = [10,13]

task['r4'] = [15,18]

task['r5'] = [7,11]

task['r6'] = [2,6]

task['r7'] = [2,6]

task['r8'] = [2,6]

task['r9'] = [12,16]

task['r10'] = [12,16]

task['r11'] = [12,16]

task['r12'] = [0,3]

listTask=list(task.items())#根据bi进行排序,结束时间早的在前面(冒泡排序)

for i in range(len(listTask)-1):for j in range(len(listTask)-i-1):if listTask[j][1][1] > listTask[j+1][1][1]:

listTask[j],listTask[j+1]=listTask[j+1],listTask[j]print(listTask)

out=[]

out.append(listTask.pop(0))defisValid(temp,out):for k inrange(len(out)):if temp[1][0]

returnFalsereturnTruefor j inrange(len(listTask)):

temp=listTask.pop(0)#判断是否相交

#相交则continue

#不相交则out.append(temp)

for k inrange(len(out)):ifisValid(temp,out):

out.append(temp)#else:continue 语句可以不写

else:continue

print(out)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是几个经典贪心算法例子Python 代码: 1. 零钱兑换问题 ''' 题目描述:给定一个整数金额和一些硬币,求出能够组成该金额的最少硬币数。 例如,当金额为 11 时,硬币面值为 [1, 2, 5],应返回 3(5元硬币1枚,2元硬币2枚)。 思路:贪心策略是每次尽可能使用面值最大的硬币,直到金额为 0。 ''' def coin_change(coins, amount): coins.sort(reverse=True) count = 0 for coin in coins: if amount == 0: break if coin <= amount: count += amount // coin amount = amount % coin return count if amount == 0 else -1 2. 活动选择问题 ''' 题目描述:假设有 n 个活动,每个活动都有一个开始时间和结束时间。选择一些活动,使得它们不冲突,且能够参加的活动数最多。 例如,有以下 6 个活动: [ (1, 4), (3, 5), (0, 6), (5, 7), (3, 8), (5, 9) ] 其中,选择 (0, 6), (6, 7), (7, 8), (8, 9) 四个活动,即可参加的活动数最多。 思路:贪心策略是每次选择结束时间最早的活动,并且该活动与前面选择的活动不冲突。 ''' def activity_selection(activities): activities.sort(key=lambda x: x[1]) selected = [] end_time = -1 for activity in activities: if activity[0] >= end_time: selected.append(activity) end_time = activity[1] return selected 3. 分糖果问题 ''' 题目描述:给定两个列表,分别表示 n 个孩子的糖果数和 m 个糖果的大小。要求将糖果分给孩子,使得每个孩子最多只能分到一个糖果,并且尽可能多的孩子能够分到糖果。 例如,有 3 个孩子,糖果大小为 [1, 2, 3],糖果数为 [1, 1],则最多只能分配 2 个孩子,因为第三个孩子没有糖果可分。 思路:贪心策略是每次尽可能给糖果大小最小且能够满足该孩子的糖果。 ''' def candy(children, candies): children.sort() candies.sort() i = j = 0 count = 0 while i < len(children) and j < len(candies): if candies[j] >= children[i]: count += 1 i += 1 j += 1 return count
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值