【发布时间】:2017-08-17 13:13:46
【问题描述】:
给定一些对称整数矩阵列表,我想删除以下等价关系下的所有重复项:
如果{1,...,k} 上有一些排列s,则两个k x k 矩阵M1 和M2 是等价的,这样对于{1,...,k} 中的所有i 和j,我们有M1_ij = M2_s(i)s(j),即两个如果我可以通过同时排列矩阵的行和列从另一个矩阵中得到一个矩阵,那么矩阵是“相等的”。
不幸的是,我的幼稚方法(在构建列表时,检查新矩阵的任何排列是否已经在列表中)被证明太慢了。
我能想到的一些可能更快的替代方法是将所有矩阵放入列表中,将它们排列为一些“规范排列”,然后按照例如所述删除重复项。 here。但是,我也不确定如何在代码中实现这样的“规范排列”。
为了进一步缩小范围:矩阵相对较小 (k <= 4),列表将包含一些 5 或 6 位数的矩阵,并且矩阵的 dtype 必须是某种整数类型(目前 @ 987654332@,但我可以更改)。
最终列表的顺序无关紧要,每个等价类的哪个代表幸存下来也无关紧要。如果需要,整个过程可能需要几个小时,但不是几天。
有没有一些相当有效的方法来实现这一点?我是否(再次)错过了一些可以帮助我解决此问题的酷 NumPy 或 SciPy 工具?
根据要求,提供一些小示例来演示该等价关系的工作原理:
矩阵{{1,1,1},{1,2,0},{1,0,3}} 和{{1,1,1},{1,3,0},{1,0,2}} 是等价的,因为排列{1,2,3}->{1,3,2} 将一个转换为另一个。
矩阵{{1,1,1},{1,2,0},{1,0,3}} 和{{1,1,0},{1,2,1},{0,1,3}} 不等价,如果不改变对角线,就不能改变 1 的位置。
【问题讨论】:
-
只是为了澄清:行和列的排列应该是相同的?
-
@MSeifert 加了一些例子,够清楚吗?
-
简短说明:同一类的两个矩阵必须具有相同的特征值。这可以进行第一次测试。考虑到您的矩阵较小,它可能相当有效。
-
说到快速测试必要条件,你可以从比较
np.sort(np.diag(M))开始。 -
为什么不在
np.all(np.sort(M.ravel()), np.sort(N.ravel()))时对所有条目进行排序和比较?!