当前位置:   article > 正文

【贪心算法】经典案例分析_贪心算法几个经典例子

贪心算法几个经典例子

目录

案例一:找零钱 

案例二:活动安排

案例三:单源最短路径


贪心算法(Greedy Algorithm)是一种基于贪心策略的算法设计方法,它在每一步选择中都采取当前状态下最优的选择,以期望达到全局最优解。贪心算法通常适用于那些具有最优子结构性质的问题,即问题的最优解可以通过子问题的最优解来构造。

贪心算法的基本思想可以简单概括为:

  1. 选择策略:在每一步,从所有可选的选择中选择当前看起来最优的那个。

  2. 局部最优:通过选择局部最优解来构建全局最优解。

  3. 无后效性:每一步的选择只依赖于当前状态,不受之后的影响。

尽管贪心算法在许多情况下能够得到高效的解决方案,但它并不适用于所有问题。因为它没有考虑全局的状态,有时可能会导致得到次优解或者根本无法得到解。


案例一:找零钱 

问题:假设你是一个收银员,你需要找给顾客一定数量的零钱。你手上有一些面额不同的硬币(比如1元、5元、10元、20元、50元)。目标是找给顾客最少数量的硬币。

方法

  1. 优先使用大面额的硬币。

  2. 如果顾客需要的金额超过当前最大面额的硬币,就使用一个最大面额的硬币,然后继续往下找零。

  3. 重复上述步骤,直到找完所有需要的零钱。

  1. def give_change(amount, coins):
  2. coins.sort(reverse=True) # 按面额从大到小排序
  3. change = [] # 用来存放找零的硬币列表
  4. for coin in coins:
  5. while amount >= coin:
  6. change.append(coin)
  7. amount -= coin
  8. return change
  9. # 测试
  10. amount = 30
  11. coins = [1, 5, 10, 20, 50]
  12. change = give_change(amount, coins)
  13. print("找零的硬币列表:", change)

案例二:活动安排

问题:假设你是一个活动策划师,现在你手上有一系列活动,每个活动都有一个开始时间和结束时间。你希望安排尽可能多的活动,但是由于时间的限制,你不能同时安排两个活动。你的目标是找出安排的最大数量的活动。

方法

  1. 首先,将所有活动按照结束时间从早到晚排序。

  2. 选择第一个结束时间最早的活动,并将其安排上日程。

  3. 依次考虑后续活动,如果活动的开始时间晚于或等于上一个活动的结束时间,则可以安排该活动。

  4. 重复上述步骤,直到所有活动都考虑完毕。 

  1. def activity_selection(start_times, end_times):
  2. # 将开始时间和结束时间打包成一个元组列表
  3. activities = list(zip(start_times, end_times))
  4. # 按结束时间从早到晚排序
  5. activities.sort(key=lambda x: x[1])
  6. selected_activities = []
  7. end_time = 0
  8. for activity in activities:
  9. start, end = activity
  10. if start >= end_time:
  11. selected_activities.append(activity)
  12. end_time = end
  13. return selected_activities
  14. # 测试
  15. start_times = [1, 3, 0, 5, 3, 5, 6, 8]
  16. end_times = [4, 5, 6, 7, 8, 9, 10, 11]
  17. selected = activity_selection(start_times, end_times)
  18. # 输出选中的活动
  19. print("选中的活动:", selected)

案例三:单源最短路径

问题:给定一个带权重的有向图和一个起始节点,我们想要找到从起始节点到图中所有其他节点的最短路径。

方法Dijkstra算法,其基本思想贪心算法。

  1. 初始化:为每个节点设置一个距离值,初始时将起始节点的距离设为0,其他节点的距离设为无穷大。将所有节点放入一个优先队列(最小堆)中,按照距离值进行排序。

  2. 选择最近节点:从优先队列中取出距离起始节点最近的节点。

  3. 更新相邻节点的距离:对于被选中的节点,遍历其所有相邻节点,更新它们的距离值。如果通过当前节点到达相邻节点的路径比之前计算的路径更短,就更新相邻节点的距离值。

  4. 重复步骤2和3:重复选择最近节点和更新相邻节点的距离,直到所有节点都被处理过或者优先队列为空。

  5. 最终结果:当所有节点都被处理完毕后,得到了从起始节点到所有其他节点的最短路径。

  1. import heapq
  2. def dijkstra(graph, start):
  3. distances = {node: float('infinity') for node in graph}
  4. distances[start] = 0
  5. priority_queue = [(0, start)]
  6. while priority_queue:
  7. current_distance, current_node = heapq.heappop(priority_queue)
  8. if current_distance > distances[current_node]:
  9. continue
  10. for neighbor, weight in graph[current_node].items():
  11. distance = current_distance + weight
  12. if distance < distances[neighbor]:
  13. distances[neighbor] = distance
  14. heapq.heappush(priority_queue, (distance, neighbor))
  15. return distances
  16. # 示例图的邻接表表示
  17. graph = {
  18. 'A': {'B': 10, 'C': 5},
  19. 'B': {'D': 5},
  20. 'C': {'B': 1, 'D': 2},
  21. 'D': {'A': 3}
  22. }
  23. # 使用Dijkstra算法找到从A到所有其他节点的最短路径
  24. shortest_paths = dijkstra(graph, 'A')
  25. # 输出最短路径
  26. for node, distance in shortest_paths.items():
  27. print(f'Shortest path from A to {node} is {distance}')

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/856670
推荐阅读
相关标签
  

闽ICP备14008679号