【问题标题】:A network flow problem need a elegant solution(python)一个网络流量问题需要一个优雅的解决方案(python)
【发布时间】:2023-02-09 22:24:25
【问题描述】:

我正在使用来自 python 的 networkx 包并且我有一个数据框

(示例数据框)

from    to     count
v0      v1     0.1
v0      v2     0.15
v0      v3     0.15
v0      v4     0.25
v0      v5     0.15
and so on..

示例图片(加权直接图)

那是我的数据框。

{'grad': {0: 'CUHK', 1: 'CUHK', 2: 'CUHK', 3: 'CUHK', 4: 'CUHK', 5: 'CityU', 6: 'CityU', 7: 'CityU', 8: 'CityU', 9: 'HKU', 10: 'HKU', 11: 'HKU', 12: 'HKUST', 13: 'HKUST', 14: 'HKUST', 15: 'HKUST', 16: 'HKUST', 17: 'HKUST', 18: 'Low Frequency', 19: 'Low Frequency', 20: 'Low Frequency', 21: 'Low Frequency', 22: 'Low Frequency', 23: 'Low Frequency', 24: 'PolyU', 25: 'PolyU', 26: 'PolyU', 27: 'PolyU'}, 'to': {0: 'CUHK', 1: 'CityU', 2: 'HKU', 3: 'LingU', 4: 'PolyU', 5: 'CityU', 6: 'HKU', 7: 'LingU', 8: 'PolyU', 9: 'CityU', 10: 'HKU', 11: 'PolyU', 12: 'CUHK', 13: 'CityU', 14: 'HKU', 15: 'HKUST', 16: 'LingU', 17: 'PolyU', 18: 'CUHK', 19: 'CityU', 20: 'HKU', 21: 'HKUST', 22: 'LingU', 23: 'PolyU', 24: 'CityU', 25: 'HKU', 26: 'LingU', 27: 'PolyU'}, 'count': {0: 9, 1: 5, 2: 3, 3: 2, 4: 3, 5: 3, 6: 2, 7: 2, 8: 3, 9: 3, 10: 9, 11: 4, 12: 2, 13: 1, 14: 2, 15: 1, 16: 4, 17: 4, 18: 49, 19: 34, 20: 29, 21: 34, 22: 3, 23: 36, 24: 1, 25: 1, 26: 1, 27: 11}}

排序的原则是当Vx -> Vy 大于Vy -> Vx 时,Vx 的排序高于Vy。

例如V0 -> V5 = 0.2 和 V5 -> V0 = 0.5 所以,V5 有更高的等级

现在我正在使用暴力法,它循环并检查所有关系。满足条件后,我会在新列表中更改它们的顺序。 -> {V0,V1,V2,V3,V4,V5,V6,V7}

我想要一个优雅的解决方案来对这些节点进行排名。也许我可以得到一些像 V5>V0 和 V0>V1 这样的部分订单,并用它们形成一个全局订单 V5>V0>V1,但我不知道如何实现它。有没有任何比蛮力更好的方法?这与任何著名问题有关吗?

【问题讨论】:

  • 我的第一个想法是将计数列降序排序,然后保留第一次看到每个梯度值的时间。所以像 df.sort_values('count', ascending=False).drop_duplicates('grad', keep='first')['grad'].tolist() 这样的东西,但我不确定它是否能按你的需要工作。此外,如果您的图片中有一个像 V1 这样的节点没有离开该节点的箭头,那么这个节点将不会被排名。
  • 您期望输出什么?
  • 我期待一份列表或任何其他总结毕业排名结果的东西。例如['HKUST', 'CUHK', 'HKU', 'CityU', 'PolyU', 'LingU']。 list[0] 代表最高的排名,这个结果是我用暴力法产生的。

标签: python pandas list networkx


【解决方案1】:

这样做的一种方法如下:

import networkx as nx
import pandas as pd

data = {'grad': {0: 'CUHK', 1: 'CUHK', 2: 'CUHK', 3: 'CUHK', 4: 'CUHK', 5: 'CityU', 6: 'CityU', 7: 'CityU', 8: 'CityU', 9: 'HKU', 10: 'HKU', 11: 'HKU', 12: 'HKUST', 13: 'HKUST', 14: 'HKUST', 15: 'HKUST', 16: 'HKUST', 17: 'HKUST', 18: 'Low Frequency', 19: 'Low Frequency', 20: 'Low Frequency', 21: 'Low Frequency', 22: 'Low Frequency', 23: 'Low Frequency', 24: 'PolyU', 25: 'PolyU', 26: 'PolyU', 27: 'PolyU'}, 
          'to': {0: 'CUHK', 1: 'CityU', 2: 'HKU', 3: 'LingU', 4: 'PolyU', 5: 'CityU', 6: 'HKU', 7: 'LingU', 8: 'PolyU', 9: 'CityU', 10: 'HKU', 11: 'PolyU', 12: 'CUHK', 13: 'CityU', 14: 'HKU', 15: 'HKUST', 16: 'LingU', 17: 'PolyU', 18: 'CUHK', 19: 'CityU', 20: 'HKU', 21: 'HKUST', 22: 'LingU', 23: 'PolyU', 24: 'CityU', 25: 'HKU', 26: 'LingU', 27: 'PolyU'}, 
          'count': {0: 9, 1: 5, 2: 3, 3: 2, 4: 3, 5: 3, 6: 2, 7: 2, 8: 3, 9: 3, 10: 9, 11: 4, 12: 2, 13: 1, 14: 2, 15: 1, 16: 4, 17: 4, 18: 49, 19: 34, 20: 29, 21: 34, 22: 3, 23: 36, 24: 1, 25: 1, 26: 1, 27: 11}}

df = pd.DataFrame(data)


G = nx.from_pandas_edgelist(df, 'grad', 'to', edge_attr='count', create_using=nx.DiGraph())
pagerank = nx.pagerank(G, weight='count')
sorted_pagerank = sorted(pagerank.items(), key=lambda x: x[1], reverse=True)

这将返回一个包含节点及其 PageRank 分数的元组列表,按 PageRank 分数的降序排序。

[('PolyU', 0.4113039270586079),
 ('HKU', 0.1945013448661985),
 ('CityU', 0.14888513201115303),
 ('LingU', 0.09978025157613143),
 ('CUHK', 0.07069262490080512),
 ('HKUST', 0.041291981078138223),
 ('Low Frequency', 0.03354473850896578)]

另一种方法是:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()

for i, row in df.iterrows():
    G.add_edge(row['grad'], row['to'], weight=row['count'])
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True)

labels = {(i, j): w['weight'] for i, j, w in G.edges(data=True)}
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)

plt.show()

这使

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    相关资源
    最近更新 更多