今日事项-2024年7月3日
事项一 收集3个实用的算法
1. 拓扑排序(Topological Sort)
产生原因与背景:
想象你正在安排一场多阶段的赛车比赛,每场比赛的开始都依赖于前一场比赛的结束。拓扑排序就是用来处理这种任务的顺序问题,确保每个任务(或比赛)在它的先决条件完成后才开始。
算法思路:
拓扑排序就像是一位赛事组织者在安排赛程,他会先列出所有比赛的依赖关系,然后确定一个顺序,使得每场比赛都在它的所有先决条件之后进行。
代码案列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| from collections import deque
def topological_sort(graph): in_degree = {u: 0 for u in graph} for u in graph: for v in graph[u]: in_degree[v] += 1
queue = deque([u for u in graph if in_degree[u] == 0]) sorted_order = []
while queue: node = queue.popleft() sorted_order.append(node)
for neighbor in graph[node]: in_degree[neighbor] -= 1 if in_degree[neighbor] == 0: queue.append(neighbor)
if len(sorted_order) != len(graph): raise ValueError("Graph has a cycle and cannot be topologically sorted")
return sorted_order
graph = { 'A': ['B', 'C'], 'B': ['D'], 'C': ['D'], 'D': [] } print("Topological sort order:", topological_sort(graph))
|
算法优缺点:
优点:拓扑排序可以高效地处理任务调度问题,时间复杂度为O(V+E),其中V是顶点数,E是边数。
缺点:如果图中存在环,拓扑排序无法完成,因为存在环意味着某些任务将永远无法开始。
解决缺点的方法:
在执行拓扑排序前,可以检测图中是否存在环,如果存在环,则报告错误或采取其他措施。
解决缺点后的代码案例:
略(上面的代码已经包含了环的检测)
算法的3个实际应用案例:
- 课程规划:安排课程顺序,确保先修课程在后修课程之前。
- 项目管理:确定项目中任务的执行顺序,以满足依赖关系。
- 依赖性解析:在软件包管理系统中,确保包的依赖性按正确的顺序安装。
2. 克鲁斯卡尔算法(Kruskal’s Algorithm)
产生原因与背景:
想象你要连接一片分散的岛屿,每座岛屿之间可以通过建造桥梁来连接,但每座桥梁的建造成本不同。克鲁斯卡尔算法就是用来找到连接所有岛屿的最小成本方案。
算法思路:
克鲁斯卡尔算法就像是一位精明的工程师在设计桥梁,他会先找出成本最低的桥梁,然后依次选择成本递增的桥梁,直到所有的岛屿都连接起来。
代码案列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| def kruskal(graph): edges = sorted(graph['edges'], key=lambda item: item[2])
parent = {node: node for node in graph['nodes']} def find(node): if parent[node] != node: parent[node] = find(parent[node]) return parent[node]
def union(node1, node2): root1 = find(node1) root2 = find(node2) if root1 != root2: parent[root2] = root1
mst_weight = 0 mst_edges = []
for node1, node2, weight in edges: root1 = find(node1) root2 = find(node2) if root1 != root2: union(node1, node2) mst_edges.append((node1, node2, weight)) mst_weight += weight
return mst_edges, mst_weight
graph = { 'nodes': ['A', 'B', 'C', 'D'], 'edges': [ ('A', 'B', 1), ('B', 'C', 3), ('C', 'D', 4), ('A', 'D', 2) ] } mst_edges, mst_weight = kruskal(graph) print("Edges in the Minimum Spanning Tree:", mst_edges) print("Total weight of the Minimum Spanning Tree:", mst_weight)
|
算法优缺点:
优点:克鲁斯卡尔算法可以高效地找到无向图的最小生成树,时间复杂度为O(E log E),其中E是边数。
缺点:如果图是稠密的,边数接近顶点数的平方,排序边的步骤可能会影响性能。
解决缺点的方法:
对于稠密图,可以考虑使用Prim算法或其他更适合稠密图的最小生成树算法。
解决缺点后的代码案例:
略(克鲁斯卡尔算法本身已经是一个高效的算法)
算法的3个实际应用案例:
- 网络设计:在设计计算机网络时,选择成本最低的连接方案。
- 电路板布线:在电路板设计中,找到连接所有组件的最短路径。
- 城市规划:在城市规划中,确定连接各个区域的最低成本交通网络。
产生原因与背景:
想象你是一位音乐制作人,需要分析一段音乐中的不同音调。傅里叶变换可以帮你将时域信号转换为频域信号,从而分析音乐的组成。
算法思路:
傅里叶变换就像是一位调音师在调音,他会听一段音乐并识别出不同频率的音调,然后将这些音调的强度和频率记录下来。
代码案列:
略(傅里叶变换的实现较为复杂,通常使用递归和迭代)
算法优缺点:
优点:快速傅里叶变换是傅里叶变换的高效实现,时间复杂度为O(n log n),非常适合处理长序列数据。
缺点:FFT要求输入数据的长度为2的幂,对于不符合要求的数据需要零填充,这可能会影响性能。
解决缺点的方法:
使用原始的傅里叶变换或其他信号处理技术来处理非2的幂长度的数据。
解决缺点后的代码案例:
略(FFT的实现通常依赖于特定的数学库)
算法的3个实际应用案例:
- 音频处理:在音频编辑和效果添加中,分析和处理音频信号。
- 图像处理:在图像压缩和分析中,转换图像数据到频域进行操作。
- 信号检测:在通信系统中,检测和分析信号中的不同频率成分。
事项二 测试WCS、WMS的导入功能