python - 将(邻接)矩阵的列和行排序为上三角
问题描述
对于有向图,我有一个约束,即邻接矩阵A
应该是具有 0 对角线的上三角形(断言非循环条件)。现在假设我任意排列了节点的顺序,这样新的邻接矩阵B
就不再是上三角矩阵了。我想要的是从中恢复A
三角矩阵B
。我可以将矩阵作为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。(在非循环条件允许的情况下完全连接)
解决方案
为了使我的pandas
解决方案能够正常工作,请将一列全为 1 的列添加到数据框中(以避免全零行):
df = pd.DataFrame([[0,1,1,0],[0,0,0,1],[0,0,1,1],[0,0,0,0]])
df.loc[:, df.shape[1]] = 1
现在您可以找到每一行中最左边的 1 的索引。索引越小,原始非置换矩阵中的行就越高。最后,按该位置对行进行排序并删除最后一列 1:
df = df.reindex(df.idxmax(1) - 1).iloc[:,:-1]
# 0 1 2 3
#0 0 1 1 0
#2 0 0 1 1
#1 0 0 0 1
#3 0 0 0 0
推荐阅读
- f# - 为什么 dotnet-fantomas 需要 FSharp.Core,Version=4.4.1.0?
- c++ - 插入指针数组删除先前的结果
- javascript - 在注入大部分html期间Angular2中的微调器
- javascript - 在外观不起作用的js中添加onlick事件侦听器
- c# - 为什么 LINQ 不喜欢内联日期计算?
- java - Java 1.8 和 tomcat 6.0.53 原因:java.io.EOFException:SSL 对等体错误关闭
- python - 使用 Django rest framework 3.6.2 和 python 3 连接到 Couchdb
- python - 在使用 **kwargs 时分配 *args
- angular - 从一个组件到另一个组件的角度路由
- html - 在 app.component.ts 内时未读取按钮功能