【发布时间】:2020-10-30 00:42:46
【问题描述】:
对于有向图,我有一个约束,即邻接矩阵A 应该是具有 0 对角线的上三角形(断言非循环条件)。现在假设我任意排列了节点的顺序,这样新的邻接矩阵B 就不再是上三角矩阵了。我想要的是从B 恢复A 三角矩阵。我可以将矩阵作为numpy.array 或pandas.DataFrame 对象,因此我正在这些库中寻找解决方案。
目前我的解决方案如下:
- 我们知道有一个节点没有父节点(一个全零列),所以我找到它,将它存储在一个数组中,然后从其他节点中删除连接
- 重复所有节点,直到创建节点的有序列表。
代码如下:
def sort_nodes(adj_matrix: np.ndarray = None):
ordered_list = []
covered_nodes = 0
while covered_nodes < adj_matrix.shape[0]:
# sum of the columns
sum_c = adj_matrix.sum(axis=0)
# find nodes with no parents: sum should be zero
parent_inds = list(np.where(sum_c == 0)[0])
# an assertion to make sure the matrix can be sorted triangular
assert len(parent_inds) != 0
# update the while condition
covered_nodes += len(parent_inds)
# add to the list
ordered_list += parent_inds
# remove parent edges by set the corresponding row to zero
adj_matrix[parent_inds, :] = 0
# eliminate from columns by assigning values so that its sum cannot be zero
adj_matrix[:, parent_inds] = 10
return ordered_list
有什么解决办法吗?一个函数或更简洁的算法。我还研究了networkx 等图形库的表面,但一无所获……干杯!
编辑:1
此类问题的一个例子是:
A:
1 2 3 4
1[[0, 1, 1, 1]
2 [0, 0, 1, 1]
3 [0, 0, 0, 1]
4 [0, 0, 0, 0]]
B:
2 1 4 3
2[[0, 0, 1, 1]
1 [1, 0, 1, 1]
4 [0, 0, 0, 0]
3 [0, 0, 1, 0]]
其中 A 是完整的顺序 DAG。 (在非循环条件允许的情况下完全连接)
【问题讨论】:
-
我们可以假设非零值都是1吗?或者图表是加权的?
-
@AminGheibi 是的,我们可以。元素是二进制的
-
您实现的称为拓扑排序(它之所以有效,是因为该图是非循环的)。您可以通过 for 循环和
sum在列上轻松地在 DataFrame 上实现此功能(与您使用的方法相同)。我在想是否有办法在熊猫中不使用 for 循环来实现它。我对此表示怀疑,因为您必须更新节点的连接并重复。 -
@AminGheibi 之前没有听过关键字“拓扑排序”。谢谢!我去看看
-
请提供一个置换矩阵的例子。任何行都可以由全 0 组成吗?
标签: python pandas numpy directed-acyclic-graphs adjacency-matrix