从 Python 中的 2 个 numpy 数组创建无向和加权图

Creating undirected and weighted graph from 2 numpy arrays in Python

在每次 for 循环迭代中,我不断生成 2 组 numpy 数组。让我们调用第一个 numpy 数组 'A' 和第二个 numpy 数组 'B'.

所以 A 看起来像这样,其中 A 的长度可以变化:

[[ 0.94 -0.04]
 [ 0.94 -0.03]
 [ 0.98 -0.01]
 [ 0.98  0.  ]
 [ 0.98  0.01]
 [ 0.99  0.01]
 [ 0.99  0.02]
 [ 0.99  0.03]
 [ 0.99  0.04]
 [ 0.99  0.94]
 [ 0.99  0.95]]

设A中的每个'vector'为无向带权图的一个节点,例如[0.94 -0.04]是一个节点,[0.94 -0.03]是另一个节点等等。

B 看起来像并且只会采用 [X,Y]:

的格式
[ 0.99 -0.01]

其中[0.99 -0.01]是另一个节点

现在我需要创建一个无向加权图,使得 [0.99 -0.01] 连接到 numpy 数组 A 中的每个节点,两个节点向量之间的权重为给定的数学公式。

例如。

[ 0.99 -0.01] connected to [ 0.94 -0.04] with scalar weight np.linalg.norm([ 0.99 -0.01] - [ 0.94 -0.04])

[ 0.99 -0.01] connected to [ 0.94 -0.03] with scalar weight np.linalg.norm([ 0.99 -0.01] - [ 0.94 -0.03])
And so on...

现在,最后一个条件是,在每次 for 循环迭代之后,您可能会得到向量组合,使得连接已经存在于图中(即向量组合的重复),在这种情况下,我们需要忽略并只寻找向量组合,这样图形就没有了,并附加图形以连接这两个具有给定权重的向量。

有人可以帮忙制定一个理想的解决方案吗?谢谢。

您收到的错误是因为 numpy.array 是可变类型,因此不可散列(请参阅 Python glossary 中的 "hashable" 条目)。如果我没记错的话 networkx 使用字典来表示引擎盖下的图形,所以我将使用 Python dict 来展示示例解决方案。如果您尝试使用 numpy.array 作为 dict 中的键,您会得到相同的 "unhashable type" 错误:

import numpy as np

b = np.array((1,2))
a = {b:"value"}

一种可能的解决方案是将其转换为不可变类型,例如元组。以下将起作用:

import numpy as np

b = np.array((1,2))
a = {tuple(b):"value"}

考虑到这一点,让我们用 networkx:

创建一个无向图
import networkx as nx
import numpy as np

#generate some random data
a = np.random.randint(low=1, high=10,size=(4,2))
b = np.random.randint(low=1, high=10,size =(2,))

#create a undirected graph
g = nx.graph.Graph()

# define a function that takes two arrays and returns a scalar -- weight
def w(a,b):
    return np.linalg.norm(b - a)

# cast np.arrays as tuples and use w to compute weights to get a list of edges
edges = [(tuple(x), tuple(b), w(x,b)) for x in a]

# add weighted edges to the graph
g.add_weighted_edges_from(edges)

# check if it worked (for a small sample)
for x in g.adjacency():
    print(x)

注意因为图是无向的,一对节点(一条边)会出现两次,所以从a到b的一条无向边,会出现两条边(a,b)和(b,a)。