【问题标题】:Generating permutation matrices of a 2 dimensional array in Python在 Python 中生成二维数组的置换矩阵
【发布时间】:2018-04-12 14:41:18
【问题描述】:

我想为输入 d(它是一个素数)生成所有平方置换矩阵。我知道有一些关于如何对所有排列执行此操作的示例,但我正在寻找满足数学定义的排列矩阵;

置换矩阵是根据数字 1 到 d 的某种置换对 dxd identity 矩阵的行进行置换而获得的矩阵。因此,每个行和列都包含一个 1,其他地方都是 0。

例如对于 2x2,[[1,0],[0,1]] 和 [[0,1],[1,0]] 满足这一点,而 [[1,1],[0,0] ],等等......不要,所以我希望这不是一个重复的问题。我有一个代码可以做到这一点,我的测试是我应该有 d!矩阵。当我达到11时,我应该得到11!矩阵,但我得到我的代码由于内存丢失而关闭的错误。我希望有人有更有效的方法来解决这个问题,因为我想使用更大的素数;

import math
import numpy as np
import cmath
from sympy.utilities.iterables import multiset_permutations
from itertools import permutations, chain
from pprint import pprint
from numpy import ndarray
from numpy import linalg as LA


d=5
print("Prime dimension",d)
a=[1]+[0 for _ in range(d-1)]
N=[] 
P=[]
Pdagger=[]
for p in multiset_permutations(a):
    N.append(p)

#Generate a list of ALL the permutation matrices including Identity (last)
for n in multiset_permutations(N):
    n
    P.append(n)
print(len(P))

如果有帮助,我将在 IPython Jupyter 笔记本中运行我的代码。我知道这可能不是运行它的最佳/最有效的方式,但我正在寻找任何人都可以给我的任何建议。顶部导入的所有库都与后面的代码相关。

【问题讨论】:

  • 11! 11x11 矩阵总共包含近 50 亿个条目,在置换矩阵的情况下,其中大部分为 0。为什么不为他们写一个生成器呢?
  • 抱歉,您能进一步解释一下吗?也许我试图回答的问题可能需要更多背景信息!
  • 11! 11x11 矩阵对于大多数机器来说太多了,无法一次保存在内存中。大概您根本不会无缘无故地尝试这样做,而是要遍历它们。 Python 中的生成器是一个惰性列表,可以动态生成元素。您应该能够编写一个生成器,以便例如你可以有一个像for M in permutation.matrices(11): 这样开始的循环
  • 如果 A 是表示为行列表的 11x11 单位矩阵,则 itertools.permutations(A)已经是所有置换矩阵的迭代器。为什么要将它们全部组装成一个数 GB 的列表?
  • 这更有意义。此时我没有理由将置换矩阵保存在内存中。 permutation.matrices 是其中的一个列表吗?另外,A 是指我的代码中的a 吗?例如 d=3、a=[1,0,0]N=[[1,0,0],[0,1,0],[0,0,1]]P 是一个矩阵列表,其中 N 的行已被置换。所以我不确定我是否理解你的评论。对于可能很明显的问题,我也深表歉意。

标签: python arrays matrix permutation


【解决方案1】:

评论太大。这是我想到的那种事情:

import itertools

def I(n):
    A = []
    for i in range(n):
        A.append([1 if j == i else 0 for j in range(n)])
    return A

#tests:

A = I(3)

for m in itertools.permutations(A):
    print('\n'.join(str(row) for row in m))
    print('')

A = I(11)
count = 0
for m in itertools.permutations(A):
    count = count + m[0][0] #for testing purposes
print(count)

输出:

[1, 0, 0]
[0, 1, 0]
[0, 0, 1]

[1, 0, 0]
[0, 0, 1]
[0, 1, 0]

[0, 1, 0]
[1, 0, 0]
[0, 0, 1]

[0, 1, 0]
[0, 0, 1]
[1, 0, 0]

[0, 0, 1]
[1, 0, 0]
[0, 1, 0]

[0, 0, 1]
[0, 1, 0]
[1, 0, 0]

3628800

运行大约需要 10 秒,最终数字是 11!/11(这是有道理的)。

【讨论】:

  • 谢谢。我们怎么会有 11!/11?这个数字在我的问题中很熟悉 d!/d 是我们拥有的等价类的数量(我计划减少问题规模的一种方法)。但是,我不确定为什么会出现这里 - 为什么我们只计算左上角元素条目为 1 的矩阵?对于我的迭代过程,我想在这里,我在这个循环中构建另一个循环,在那里我将 m 作为置换矩阵向前推进。
  • 我只是在计算左上角为 1 的矩阵——11 个矩阵中有 1 个具有此属性。这是一个随机测试——我只是想对生成的每个矩阵做一些事情