我正在使用networkx(用于python的库来处理图形)。我基本上有各种边缘的节点,但是如果它使用了连接最多的节点,我想看看路径是什么样的。
我可以使用此命令查看连接数:
len(G.edges(CurrentNode))
我可以获得边数,但我不知道如何将其应用于列表作为路径。例如,我可以将此数字添加为属性,但我不认为在查找路径时会考虑属性,并且因为我在连接边缘后添加此数字,所以我无法将权重添加到边缘本身。另一个问题是分数越高,我想要跟随的路径越多,但是我认为边缘跟随最低的加权边缘。
我想知道其他人根据节点的某些特征采取什么方法来寻找路径?如果有人知道如何为networkx做这件事,太好了!但我认为networkx有很多功能,所以如果我能得到理论或一般方法,我相信我能找到一种方法在python中实现它。
更新:对不起我可能会解释错了。我知道我可以向节点添加属性,但我不确定如何根据这些属性做出路径决策。所以在我的情况下,基于某些条件,我在节点之间添加边缘。每组节点代表不同的一天(day1data ..,day2data ..,day3data ..),所以我只在某些规则匹配时才将第一天的几个节点连接到第二天的节点。一旦我连接了边缘,我希望在选择路径时考虑那些边缘。所以我在当前每个节点添加了一个属性'weight',它基本上是连接该节点的边的总数。 我的问题是,权重属性不用于任何路径决策,因为它是我创建并标记自己的属性(我可以创建一个名为'abc'='hello world'的标签,它会将该属性应用于节点)。如何在创建路径时考虑这个权重(边缘已经创建,所以我不认为我可以返回并重新创建它们)?
答案 0 :(得分:6)
您当然可以在NetworkX中为边缘添加权重。实际上,您可以为边设置任意数据,因为它基本上是dict
。
In [30]: import networkx as nx
In [31]: G = nx.Graph()
In [32]: G.add_edge(1, 2, weight=3, type="green")
In [33]: G[1][2]
Out[33]: {'type': 'green', 'weight': 3}
In [34]: G[1][2]["weight"]
Out[34]: 3
此外,您可以在添加边之后更改边(或节点)的参数。
In [35]: G[1][2]["weight"] = 5
In [36]: del G[1][2]["type"]
In [37]: G[1][2]["color"] = "green"
In [38]: G[1][2]
Out[38]: {'color': 'green', 'weight': 5}
您当然可以根据权重(或权重参数中指定的任何其他属性)计算路径。
In [39]: G.add_edge(1, 3, weight=1)
In [40]: G.add_edge(2, 3, weight=2)
In [41]: G.edges()
Out[41]: [(1, 2), (1, 3), (2, 3)]
In [42]: nx.shortest_path(G, source=1, target=2, weight="weight")
Out[42]: [1, 3, 2]
对于您的情况,决定边缘权重可能会很棘手。请记住,加权最短路径通常使用Djikstra's Algorithm来计算,并且它有利于较小的权重。它还需要正重量。一种可能的解决方案是将权重1/max(k_i,k_j)
分配给边(i,j)
,其中k_i
,k_j
是节点i
和j
。
计算转移概率上的最短路径的正确方法是将边权重变换为表示惊人的:即概率的负对数。这导致权重为正,并且任何给定的最短路径然后被解释为最小化意外。由于Dijkstra的算法总结了权重,它在日志空间中这样做,这意味着它实际上是乘以概率。为了恢复观察任何给定最短路径的联合概率,那么,你只需采取负面意外的指数。
答案 1 :(得分:0)
>>> G.add_edge(1, 2, weight=4.7 )
>>> G.add_edges_from([(3,4),(4,5)], color='red')
>>> G.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})])
>>> G[1][2]['weight'] = 4.7
>>> G.edge[1][2]['weight'] = 4
看起来可以在事后添加权重。
答案 2 :(得分:0)
考虑自制attribute
的唯一方法是在框架中编辑文件。
您要查找的文件是networkx/algorithms/shortest_paths/weighted.py
将会有get_weight
function
的lambda声明,如下所示:
if G.is_multigraph():
get_weight = lambda u, v, data: min(
eattr.get(weight, 1) for eattr in data.values())
else:
get_weight = lambda u, v, data: data.get(weight, 1)
我想给我的node
一定的重量,所以我修改了它:
if G.is_multigraph():
get_weight = lambda u, v, data: min(
eattr.get(weight, 1) for eattr in data.values())
else:
get_weight = lambda u, v, data: (data.get(weight,0) + nx.get_node_attributes(G, "node_weight").get(v,0))
我将默认边缘权重设置为0:data: data.get(weight,0)
并添加了我自己的属性值" node_weight" (默认为0)。
data: (data.get(weight,0) + nx.get_node_attributes(G, "node_weight").get(v,0))
v
是图表中下一个可访问的node
。
现在,您可以在创建图表后设置attribute
。
nx.set_node_attributes(G, "node_weight", {1:3.5, 2:56})