基于Pandas DataFrame的关键路径网络流构建、时长计算及可视化问询
关键路径问题解决方案:路径时长计算与可视化
一、计算所有路径的总时长
将活动依赖关系转换为有向图结构,通过深度优先搜索(DFS)遍历所有从起始节点(无前置活动)到终点G的路径,并计算每条路径的总时长。
实现代码
import pandas as pd from collections import defaultdict # 初始化原始数据 Activity = ['A','B','C','D','E','F','G'] Predecessor = [None, None, None, 'A', 'C', 'A', ['B','D','E']] Durations = [2,6,4,3,5,4,2] df = pd.DataFrame(zip(Activity, Predecessor, Durations), columns = ['Activity','Predecessor','Durations']) # 构建邻接表:key为前置活动,value为(后续活动, 后续活动时长) adj = defaultdict(list) duration_map = {row['Activity']: row['Durations'] for _, row in df.iterrows()} for _, row in df.iterrows(): act = row['Activity'] preds = row['Predecessor'] if preds is None: continue # 处理单个或多个前置活动的情况 if isinstance(preds, list): for p in preds: adj[p].append((act, duration_map[act])) else: adj[preds].append((act, duration_map[act])) # 确定起始节点(无前置活动)和目标节点 start_nodes = df[df['Predecessor'].isna()]['Activity'].tolist() target_node = 'G' # DFS遍历所有路径并计算总时长 all_paths = [] def dfs(current, path, total_duration): if current == target_node: all_paths.append((path + [current], total_duration)) return # 遍历当前节点的所有后续节点 for neighbor, dur in adj.get(current, []): dfs(neighbor, path + [current], total_duration + dur) # 对每个起始节点执行DFS for start in start_nodes: dfs(start, [], duration_map[start]) # 整理结果为DataFrame result_df = pd.DataFrame(all_paths, columns=['路径', '总时长']) print(result_df)
输出结果
路径 总时长 0 [A, D, G] 7 1 [B, G] 8 2 [C, E, G] 11
二、网络流可视化
方案1:NetworkX + Matplotlib(静态可视化)
使用NetworkX构建有向图,结合Matplotlib生成静态网络图,清晰展示活动依赖关系及时长。
实现代码
import networkx as nx import matplotlib.pyplot as plt # 构建有向图 G = nx.DiGraph() G.add_nodes_from(df['Activity']) # 添加边及时长属性 for _, row in df.iterrows(): act = row['Activity'] preds = row['Predecessor'] if preds is None: continue if isinstance(preds, list): for p in preds: G.add_edge(p, act, weight=row['Durations']) else: G.add_edge(preds, act, weight=row['Durations']) # 设置固定布局 pos = nx.spring_layout(G, seed=42) # 绘制节点、边及标签 nx.draw_networkx_nodes(G, pos, node_size=1500, node_color='lightblue') nx.draw_networkx_edges(G, pos, arrowstyle='->', arrowsize=20) nx.draw_networkx_labels(G, pos, font_size=12, font_weight='bold') edge_labels = nx.get_edge_attributes(G, 'weight') nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=10) # 调整布局并展示 plt.tight_layout() plt.axis('off') plt.show()
方案2:PyVis(交互式可视化)
PyVis可生成交互式HTML网络图,支持拖拽节点、缩放视图,适合复杂流程的可视化。
实现代码
from pyvis.network import Network # 初始化交互式有向图 net = Network(directed=True, height='600px', width='100%', bgcolor='#222222', font_color='white') # 添加节点和边(标注时长) for _, row in df.iterrows(): act = row['Activity'] net.add_node(act, label=act, size=20) preds = row['Predecessor'] if preds is None: continue if isinstance(preds, list): for p in preds: net.add_edge(p, act, label=str(row['Durations']), width=2) else: net.add_edge(preds, act, label=str(row['Durations']), width=2) # 生成HTML文件 net.show('activity_network.html')
运行后会生成activity_network.html,打开即可查看交互式网络图。
内容的提问来源于stack exchange,提问作者Mr_Rakhman
相关产品推荐
相关产品推荐

