import pandas as pd import networkx as nx # 读取数据 data = pd.read_excel('附件1.xlsx') # 构建有向图 G = nx.DiGraph() for _, row in data.iterrows(): source = row['发货城市'] target = row['收货城市'] weight = row['快递数量'] if not G.has_edge(source, target): G.add_edge(source, target, weight=weight) else: G[source][target]['weight'] += weight # 计算节点的入度和出度 in_degree = dict(G.in_degree(weight='weight')) out_degree = dict(G.out_degree(weight='weight')) # 归一化处理 total_in = sum(in_degree.values()) total_out = sum(out_degree.values()) for node in G.nodes(): if total_in > 0: in_degree[node] /= total_in if total_out > 0: out_degree[node] /= total_out # 计算 PageRank 值 pr = nx.pagerank(G, weight='weight') # 排序输出结果 result = sorted(pr.items(), key=lambda x: x[1], reverse=True)[:5] for i, (node, score) in enumerate(result): print(f'{i+1}. {node} ({score:.4f})')
时间: 2024-03-29 11:36:43 浏览: 22
这段代码是使用 Python 的 pandas 和 networkx 库读取 Excel 中的数据,构建有向图,并进行 PageRank 计算,最后输出 PageRank 值最高的前五个节点。
具体步骤如下:
1. 读取 Excel 中的数据,存储在一个 pandas 的 DataFrame 中。
2. 构建有向图,使用 DiGraph() 函数创建一个有向图对象 G。
3. 遍历 DataFrame 中的每一行数据,将发货城市和收货城市作为有向图中的节点,将快递数量作为边的权重。
4. 如果有向图中不存在该边,则添加该边并设置权重为当前的快递数量;否则,将该边的权重加上当前的快递数量。
5. 计算每个节点的入度和出度,使用 in_degree() 和 out_degree() 函数分别计算每个节点的入度和出度,并将权重归一化处理。
6. 计算 PageRank 值,使用 pagerank() 函数计算有向图中每个节点的 PageRank 值,并将权重设置为边的权重。
7. 排序输出结果,使用 sorted() 函数对 PageRank 值进行排序,并输出 PageRank 值最高的前五个节点及其对应的值。
总的来说,这段代码可以用于分析快递运输网络中的节点重要性,找出最重要的节点,以便进行优化和改进。
相关问题
import pandas as pd import networkx as nx import matplotlib.pyplot as plt df = pd.read_excel(r"C:\Users\li'yi'jie\Desktop\运筹学网络规划数据.xlsx") edges = [] for i in range(len(df)): edge = { "id": df.loc[i, "边的编号"], "tail": df.loc[i, "边的尾节点"], "head": df.loc[i, "边的头节点"], "length": df.loc[i, "长度"], "capacity": df.loc[i, "容量"] } edges.append(edge) plt.figure(figsize=(10,8)) G = nx.DiGraph() for edge in edges: G.add_edge(edge["tail"], edge["head"], weight=edge["length"]) all_pairs = dict(nx.all_pairs_dijkstra_path_length(G)) pos = nx.spring_layout(G) nx.draw(G, pos, with_labels=True) labels = nx.get_edge_attributes(G, "weight") nx.draw_networkx_edge_labels(G, pos, edge_labels=labels, label_pos=0.3) plt.show()如何让生成的有向图两只箭头分开
可以使用 `nx.draw_networkx_edge_labels()` 函数的 `label_pos` 和 `font_size` 参数来调整边权重标签的位置和大小,从而避免标签与箭头重叠。同时,可以使用 `nx.draw_networkx_edges()` 函数的 `arrowsize` 参数来调整箭头大小。修改后的代码如下所示:
```
import pandas as pd import networkx as nx import matplotlib.pyplot as plt df = pd.read_excel(r"C:\Users\li'yi'jie\Desktop\运筹学网络规划数据.xlsx") edges = [] for i in range(len(df)): edge = { "id": df.loc[i, "边的编号"], "tail": df.loc[i, "边的尾节点"], "head": df.loc[i, "边的头节点"], "length": df.loc[i, "长度"], "capacity": df.loc[i, "容量"] } edges.append(edge) plt.figure(figsize=(10,8)) G = nx.DiGraph() for edge in edges: G.add_edge(edge["tail"], edge["head"], weight=edge["length"]) all_pairs = dict(nx.all_pairs_dijkstra_path_length(G)) pos = nx.spring_layout(G) nx.draw(G, pos, with_labels=True, arrowsize=20) labels = nx.get_edge_attributes(G, "weight") nx.draw_networkx_edge_labels(G, pos, edge_labels=labels, label_pos=0.3, font_size=12) plt.show()
```
运行后可以看到箭头和边权重标签已经分开,且箭头大小也被调整为了 20。您可以适当调整 `arrowsize` 参数的值,以达到最佳效果。
import pandas as pd import numpy as np import networkx as nx # 读取Excel文件中的邻接矩阵 adjacency_matrix = pd.read_excel('output.xlsx', index_col=0) # 将邻接矩阵转换为numpy数组 adjacency_matrix = adjacency_matrix.to_numpy() # 创建有向图对象 G = nx.DiGraph(adjacency_matrix) def preprocess(G): p = 0 directedGraph = nx.DiGraph() for u in G.nodes(): for v in G.neighbors(u): if (v != u): # propProb = G.number_of_edges(u, v) / G.in_degree(v) propProb = G.number_of_edges(u, v) / G.degree(v) directedGraph.add_edge(u, v, pp=propProb) # p += propProb # print(propProb) # print('平均阈值:', p/2939) return directedGraph def simulate(G, seedNode, propProbability): newActive = True currentActiveNodes = copy.deepcopy(seedNode) newActiveNodes = set() activatedNodes = copy.deepcopy(seedNode) # Biar ga keaktivasi 2 kali influenceSpread = len(seedNode) while (newActive): for node in currentActiveNodes: for neighbor in G.neighbors( node): # Harus dicek udah aktif apa belom, jangan sampe ngaktifin yang udah aktif if (neighbor not in activatedNodes): if (G[node][neighbor]['pp'] > propProbability): # flipCoin(propProbability) newActiveNodes.add(neighbor) activatedNodes.append(neighbor) influenceSpread += len(newActiveNodes) if newActiveNodes: currentActiveNodes = list(newActiveNodes) newActiveNodes = set() else: newActive = False # print("activatedNodes",len(activatedNodes),activatedNodes) return influenceSpread def flipCoin(probability): return random.random() < probability解释一下这个代码
这代码是一个传播模型的实现,用于模拟信息在一个有向图中的传播过程。首先,它读取一个Excel文件,其中包含了一个邻接矩阵,表示图中节点之间的连接关系。然后,将邻接矩阵转换为numpy数组,并创建一个有向图对象。
preprocess函数用于预处理图对象,它遍历所有节点,并计算每条边的传播概率(propProbability),然后将这些边添加到有向图中。
simulate函数用于模拟信息的传播过程。它接受一个种子节点(seedNode)和传播概率(propProbability)作为输入。通过迭代算法,不断将新激活的节点加入到currentActiveNodes集合中,并计算影响范围(influenceSpread)。直到没有新激活的节点时,传播过程结束。
最后,flipCoin函数用于模拟抛硬币的过程,以给定的概率返回True或False。在simulate函数中,它用于判断节点是否被激活。
总体上,这段代码实现了一个简单的信息传播模型,并可以根据传播概率和种子节点模拟信息在有向图中的传播过程。