贪心算法——基于Python

“贪心”的含义

        贪心算法(Greedy Algorithm)是一种常见的算法设计策略,用于解决优化问题。在贪心算法中,每一步都采取当前状态下最优的选择,而不考虑该选择对未来的影响。这种策略在每一步都寻找局部最优解,希望通过一系列局部最优解的组合来达到全局最优解。

        贪心算法的基本思想是通过不断地做出局部最优选择,直到达到全局最优解。然而,由于它只关注当前步骤的最优解,而不是考虑全局的长远影响,所以并不是所有问题都适合使用贪心算法。在某些情况下,贪心算法可能会得到次优解或者根本无法得到正确解。

        要使用贪心算法解决问题,通常需要满足以下两个关键性质:

  1. 贪心选择性质(Greedy Choice Property):在每一步都做出局部最优选择,即当前情况下看起来最好的选择。

  2. 最优子结构性质(Optimal Substructure Property):问题的全局最优解可以通过一系列局部最优解来达到。

        常见的应用贪心算法的问题包括找零钱问题、活动选择问题、背包问题(部分情况下)、最短路径问题(部分情况下)等。贪心算法在某些情况下可以高效地求解问题,但在一些复杂的问题中,可能需要结合其他算法或策略来得到正确的解答。

找零问题:

问题描述:

        假设有以下硬币面额:1元、5元、10元、25元。现在需要找零32元,问如何找零使得硬币数量最少?

        使用贪心算法的思路是每次选择最大面额的硬币,直到剩余金额为0。在这个示例中,可以按以下步骤进行:

  1. 找一个面额最大的硬币,小于等于目标金额:25元,剩余金额为32 - 25 = 7元。
  2. 继续找一个面额最大的硬币,小于等于剩余金额:5元,剩余金额为7 - 5 = 2元。
  3. 找一个面额最大的硬币,小于等于剩余金额:1元,剩余金额为2 - 1 = 1元。
  4. 找一个面额最大的硬币,小于等于剩余金额:1元,剩余金额为1 - 1 = 0元。

        在这个例子中,使用了2个1元硬币、1个5元硬币和1个25元硬币,总共4个硬币,实现了找零32元。这种情况下贪心算法得到了最优解,但并非所有情况下贪心算法都能得到最优解。

        需要注意的是,贪心算法并不适用于任何情况,因为它只关注局部最优解,可能会在某些情况下导致次优解。在硬币面额不是常见的 1、5、10、25 这种特殊情况下,贪心算法可能无法得到最优解。

代码实现:

def coin_change_greedy(coins, amount):
    coins.sort(reverse=True)  # 从大到小排序
    num_coins = 0
    i = 0
    
    while amount > 0 and i < len(coins):
        if coins[i] <= amount:
            num_coins += 1
            amount -= coins[i]
        else:
            i += 1
            
    if amount == 0:
        return num_coins
    else:
        return -1  # 无法找零

# 示例硬币面额和目标金额
coins = [1, 5, 10, 25]
amount = 32

result = coin_change_greedy(coins, amount)
if result != -1:
    print(f"最少需要 {result} 枚硬币来找零 {amount} 元。")
else:
    print("无法找零。")

活动策划问题:

问题描述:

        假设你参加了一个会议,会议的日程安排如下:

活动开始时间结束时间
A14
B35
C06
D57
E38
F59
G610
H811
I812
J213
K1214

        现在的问题是,如何选择一组活动,使得你能够参加尽可能多的活动,而且这些活动的时间段不能相互重叠?

        使用贪心算法解决这个问题的思路是,首先按照活动的结束时间从小到大对活动进行排序。然后从第一个活动开始,选择结束时间最早的活动,并且确保所选活动的时间段不与之前选择的活动相重叠。在这个例子中,按照结束时间排序后的活动序列是:

活动开始时间结束时间
C06
A14
J213
B35
E38
D57
F59
G610
H811
I812
K1214

        使用贪心算法,按照上述排序选择活动,你可以参加的活动数量最多,共有 8 个活动:C、A、B、D、G、H、I、K。

        这个例子演示了活动选择问题中贪心算法的应用,通过每次选择结束时间最早的活动来获得局部最优解,最终达到全局最优解,即参加尽可能多的活动。

代码实现:

def activity_selection(start_times, finish_times):
    n = len(start_times)
    activities = list(zip(start_times, finish_times))
    activities.sort(key=lambda x: x[1])  # 按结束时间排序
    selected_activities = [activities[0]]
    
    last_finish_time = activities[0][1]
    
    for i in range(1, n):
        if activities[i][0] >= last_finish_time:
            selected_activities.append(activities[i])
            last_finish_time = activities[i][1]
    
    return selected_activities

# 示例活动的开始时间和结束时间
start_times = [1, 3, 0, 5, 8, 5, 6, 8, 8, 2, 12]
finish_times = [4, 5, 6, 7, 9, 9, 10, 11, 12, 13, 14]

selected = activity_selection(start_times, finish_times)
print("选择的活动:")
for activity in selected:
    print(f"开始时间:{activity[0]}, 结束时间:{activity[1]}")

 背包问题将会和后期智能算法一起讲解

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值