### 如何使用 Python 实现贪心算法
#### 贪心算法简介
贪心算法是一种通过局部最优选择逐步构建全局最优解的方法。它适用于那些具有 **贪心选择性质** 的问题,即每一步的选择都可以独立于后续决策而达到整体最优效果[^1]。
---
#### 示例一:求解背包问题
背包问题是经典的优化问题之一,目标是在不超过容量的情况下最大化物品总价值。下面是一个基于贪心策略的 Python 解决方案:
```python
def knapsack_greedy(capacity, items):
"""
使用贪心算法解决背包问题。
:param capacity: 背包的最大容量
:param items: 物品列表 [(重量, 价值), ...]
:return: (选中的物品列表, 总价值)
"""
# 按单位价值降序排列
items = sorted(items, key=lambda x: x[1]/x[0], reverse=True)
total_value = 0
knapsack = []
for weight, value in items:
if capacity >= weight:
knapsack.append((weight, value))
capacity -= weight
total_value += value
return knapsack, total_value
# 测试数据
items = [(2, 40), (3.14, 50), (1.98, 100), (5, 95)]
capacity = 7
selected_items, max_value = knapsack_greedy(capacity, items)
print(f"选中的物品: {selected_items}")
print(f"最大总价值: {max_value}")
```
上述代码实现了按单位价值排序并依次选取物品的过程,直到无法再放入更多物品为止[^4]。
---
#### 示例二:Dijkstra 算法(最短路径)
Dijkstra 是一种用于计算加权图中最短路径的经典贪心算法。以下是其 Python 实现方式:
```python
import heapq
def dijkstra(graph, start_node):
"""
使用 Dijkstra 算法计算单源最短路径。
:param graph: 图表示为邻接表字典 {节点: {(邻居节点, 权重)}}
:param start_node: 起始节点
:return: 到各节点的距离字典
"""
distances = {node: float('inf') for node in graph} # 初始化距离无穷大
distances[start_node] = 0 # 起点到自身的距离为零
priority_queue = [(0, start_node)] # 小根堆存储当前待扩展节点
while priority_queue:
current_distance, current_node = heapq.heappop(priority_queue)
# 如果已访问过该节点,则跳过
if current_distance > distances[current_node]:
continue
# 遍历相邻节点更新距离
for neighbor, edge_weight in graph.get(current_node, []):
distance = current_distance + edge_weight
# 更新更优路径
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(priority_queue, (distance, neighbor))
return distances
# 测试数据
graph = {
'A': [('B', 1), ('C', 4)],
'B': [('A', 1), ('C', 2), ('D', 6)],
'C': [('A', 4), ('B', 2), ('D', 3)],
'D': [('B', 6), ('C', 3)]
}
start_node = 'A'
shortest_distances = dijkstra(graph, start_node)
for node, dist in shortest_distances.items():
print(f"{start_node} -> {node}: {dist}")
```
此实现利用优先队列加速搜索过程,并始终选择当前未处理节点中最近的一个作为下一步扩展对象[^2]。
---
#### 示例三:活动安排问题
假设有一组需要占用相同资源的任务集合,每个任务都有开始时间和结束时间。我们的目标是尽可能多地完成这些任务。这是一个典型的贪心应用场景:
```python
def activity_selection(activities):
"""
使用贪心算法解决活动安排问题。
:param activities: 每项活动的时间区间 [(起始时间, 结束时间)...]
:return: 最多可执行的活动子集
"""
# 按照结束时间升序排序
activities = sorted(activities, key=lambda x: x[1])
selected_activities = [activities[0]]
last_end_time = activities[0][1]
for act_start, act_end in activities[1:]:
if act_start >= last_end_time:
selected_activities.append((act_start, act_end))
last_end_time = act_end
return selected_activities
# 测试数据
activities = [(1, 3), (2, 5), (4, 6), (6, 8), (7, 9)]
result = activity_selection(activities)
print("最多能完成的活动:", result)
```
这里采用了按照最早结束时间挑选下一个可用活动的原则来保证最终结果数量最大。
---
### 注意事项
尽管贪心方法简单高效,在某些情况下可能无法获得真正的全局最优解。因此实际应用前需仔细验证是否满足贪心选择性质[^3]。