# 探索贪心算法：解决优化问题的高效策略

## 贪心算法的基本概念

### 贪心算法的特点

1. 局部最优选择：每一步都选择当前状态下最优的操作。
2. 无需回溯：一旦做出选择，便不会更改。
3. 逐步构建解决方案：从一个初始解开始，通过局部最优选择逐步构建完整解决方案。

## 贪心算法的应用场景

### 1. 活动选择问题

def activity_selection(activities):
activities.sort(key=lambda x: x[1])  # 按结束时间排序
selected_activities = [activities[0]]

for i in range(1, len(activities)):
if activities[i][0] >= selected_activities[-1][1]:
selected_activities.append(activities[i])

return selected_activities

activities = [(0, 6), (1, 4), (3, 5), (5, 7), (3, 9), (5, 9), (6, 10), (8, 11), (8, 12), (2, 14), (12, 16)]
selected = activity_selection(activities)
print("Selected activities:", selected)

### 2. 背包问题（分数背包）

def fractional_knapsack(items, capacity):
items.sort(key=lambda x: x[1] / x[0], reverse=True)  # 按价值密度排序
total_value = 0.0
for weight, value in items:
if capacity >= weight:
total_value += value
capacity -= weight
else:
total_value += value * (capacity / weight)
break

items = [(10, 60), (20, 100), (30, 120)]  # (weight, value)
capacity = 50
max_value = fractional_knapsack(items, capacity)
print("Maximum value in knapsack:", max_value)

### 3. 最小生成树（Kruskal 算法）

class DisjointSet:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n

def find(self, u):
if self.parent[u] != u:
self.parent[u] = self.find(self.parent[u])
return self.parent[u]

def union(self, u, v):
root_u = self.find(u)
root_v = self.find(v)
if root_u != root_v:
if self.rank[root_u] > self.rank[root_v]:
self.parent[root_v] = root_u
elif self.rank[root_u] < self.rank[root_v]:
self.parent[root_u] = root_v
else:
self.parent[root_v] = root_u
self.rank[root_u] += 1

def kruskal(n, edges):
ds = DisjointSet(n)
edges.sort(key=lambda x: x[2])
mst = []
for u, v, weight in edges:
if ds.find(u) != ds.find(v):
ds.union(u, v)
mst.append((u, v, weight))
return mst

edges = [(0, 1, 10), (0, 2, 6), (0, 3, 5), (1, 3, 15), (2, 3, 4)]
n = 4  # Number of vertices
mst = kruskal(n, edges)
print("Edges in MST:", mst)

## 贪心算法的局限性

posted @ 2024-07-13 16:58  最小生成树  阅读(195)  评论(0编辑  收藏  举报