Python 我将如何找到一个4x4矩阵的所有可能的置换,其中包含静态角元素?

Python 我将如何找到一个4x4矩阵的所有可能的置换,其中包含静态角元素?,python,math,matrix,permutation,itertools,Python,Math,Matrix,Permutation,Itertools,到目前为止,我一直在使用python生成矩阵排列,以查找幻方。到目前为止(对于3x3矩阵),我一直在做的是使用itertools.permutations找到集合{1,2,3,4,5,6,7,8,9}的所有可能的置换,将它们存储为列表,进行计算并打印结果 现在我想找出四阶幻方。因为找到所有排列意味着16!可能性,我想通过在角上放置可能的元素来提高效率,例如1,16在对角一角上,4,13在对角二角上 所以我的问题是如何找到集合{1,2….16}的置换,其中一些元素没有移动,只要从置换集中取出放置的

到目前为止,我一直在使用python生成矩阵排列,以查找幻方。到目前为止(对于3x3矩阵),我一直在做的是使用itertools.permutations找到集合{1,2,3,4,5,6,7,8,9}的所有可能的置换,将它们存储为列表,进行计算并打印结果

现在我想找出四阶幻方。因为找到所有排列意味着16!可能性,我想通过在角上放置可能的元素来提高效率,例如1,16在对角一角上,4,13在对角二角上


所以我的问题是如何找到集合{1,2….16}的置换,其中一些元素没有移动,只要从置换集中取出放置的数字就可以了。然后将它们插入到生成的排列中的适当位置

举个例子,你可以把1,16,4,13去掉。排列在(2、3、5、6、7、8、9、10、11、12、14、15)上,对于每个排列,在您预先选择放置它们的位置插入1、16、4、13。

\Rajiv Ravishankar
#Rajiv Ravishankar
#rravisha
#21-301 Assignment #1, Qns 4

from numpy import matrix
import itertools

def eligCheck(m):
    #We know certain properties of magic squares that can help identify if a 3x3 matrix is a magic square or not
    #These properties include the following checks listed below.
    #
    #
    #The main purpose of this function is to check is a 3x3 matrix is a magic square without having to add all the 
    #rows, columns and diagonals.
    flag=0
    #Check 1 if the matrix is indeed 4x4
    if (len(m)==4 and len(m[0])==4 and len(m[1])==4 and len(m[2])==4):
        flag=flag+1
    #Check 2 if the 2nd diagonal adds up
    if (m[0][3] + m[1][2] + m[2][1] + m[3][0] == 34):
        flag=flag+1
    #Checks 2 if the first diagonal adds up 
    if (m[0][0] + m[1][1] + m[2][2] + m[3][3] == 34):
        flag=flag+1
    #To save resources and increase efficency, only if all three checks return true will we add the rows and columns to check.      
    if (flag==3):
        return True
    else:
        return False

def elementAdder(m):
    #This function is to be called only AFTER eligCheck() returns TRUE for a given matrix.  Since a 4x4 matrix that satisfies the checks 
    #in eligCheck() does not mean that it is a magic square, we add each row, each column and both diagonals an see if the sum
    #is equal to 15.  Splitting into two function save processing power.
    #
    #
    #Checking if all rows add up to 15
    flag=0
    #Check 1 if row 1 adds up
    if (m[0][0]+m[0][1]+m[0][2]+m[0][3] == 34):
        flag=flag+1
    else:
        return False
    #Check 2 if row 2 adds up   
    if (m[1][0]+m[1][1]+m[1][2]+m[1][3] == 34):
        flag=flag+1
    else:
        return False    
    #Check 3 if row 3 adds up
    if (m[2][0]+m[2][1]+m[2][2]+m[2][3] == 34):
        flag=flag+1
    else:
        return False
    #Check if row 4 adds up
    if (m[3][0]+m[3][1]+m[3][2]+m[3][3] == 34):
        flag=flag+1
    else:
        return False    
    #Check 4 if column 1 adds up    
    if (m[0][0]+m[1][0]+m[2][0]+m[3][0] == 34):
        flag=flag+1
    else:
        return False
    #Check 5 if column 2 adds up    
    if (m[0][1]+m[1][1]+m[2][1]+m[3][1] == 34):
        flag=flag+1
    else:
        return False
    #Check 6 if column 3 adds up
    if (m[0][2]+m[1][2]+m[2][2]+m[3][2] == 34):
        flag=flag+1
    else:
        return False
    #Check 7 if column 4 adds up    
    if (m[0][3]+m[1][3]+m[2][3]+m[3][3] == 34):
        flag=flag+1
    else:
        return False
    #Note that diagonal checks have already been verified in eligCheck() represents the diagonal from left to right

    #The strategy here is to set flag as zero initially before the additiong checks and then run each check one after the other.  If a
    #check fails, the matrix is not a magic square.  For every check that passes, flag is incremented by 1.  Therefore, at the end of 
    #all the check, if flag == 8, it is added proof that the matrix is a magic square.  This step is redundant as the program has been 
    #written to stop checks as soon as a failed check is encountered as all checks need to be true for a magic square.
    if flag==8:
        print m
        return True
    else:
        print "**** FLAG ERROR: elementAdder(): Line 84 ***" 
        print m

def dimensionScaler(n, lst):
    #This function converts and returns a 1-D list to a 2-D list based on the order.  #Square matrixes only.
    #n is the order here and lst is a 1-D list.
    i=0
    j=0
    x=0
    #mat = [[]*n for x in xrange(n)]
    mat=[]
    for i in range (0,n):
        mat.append([])
        for j in range (0,n):
            if (j*n+i<len(lst)):
                mat[i].append(lst[i*n+j])
    return mat

#mtrx=[]

def matrixGen():
#Brute forcing all possible 4x4 matrices according to the previous method will require 16!*32*16 bits or 1.07e6 GB of memory to be allocated in the RAM (impossible today)./, we 
#use an alternative methos to solve this problem.
#
#
#We know that for the sums of the diagonals will be 34 in magic squares of order 4, so we can make some assumtions of the corner element values 
#and also the middle 4 elements.  That is, the values of the diagonals.
#The strategy here is to assign one set of opposite corner elements as say 1 and 16 and the second as 13 and 4
#The remaining elements can be brute forced for combinations untill 5 magic squares are found.
    setPerms=itertools.permutations([2,3,5,6,7,8,9,10,11,12,14,15],12)
    final=[0]*16
    count=0
    #print final
    for i in setPerms:
        perm=list(i)
        setCorners=list(itertools.permutations([1,4,13,16],4))


        for j in range(0,len(setCorners)):
            final[0]=setCorners[j][0]
            final[1]=perm[0]
            final[2]=perm[1]
            final[3]=setCorners[j][1]
            final[4]=perm[2]
            final[5]=perm[3]
            final[6]=perm[4]
            final[7]=perm[5]
            final[8]=perm[6]
            final[9]=perm[7]
            final[10]=perm[8]
            final[11]=perm[9]
            final[12]=setCorners[j][2]
            final[13]=perm[10]
            final[14]=perm[11]
            final[15]=setCorners[j][3]
            if eligCheck(dimensionScaler(4,final))==True:
                elementAdder(dimensionScaler(4,final))

matrixGen()
#拉维沙 #21-301作业#1,问题4 从numpy导入矩阵 进口itertools def eligCheck(m): #我们知道幻方的某些性质,可以帮助识别3x3矩阵是否为幻方 #这些属性包括下列检查。 # # #此函数的主要目的是检查3x3矩阵是否为幻方,而无需添加所有 #行、列和对角线。 标志=0 #检查1矩阵是否确实为4x4 如果(len(m)==4和len(m[0])==4和len(m[1])==4和len(m[2])==4): 标志=标志+1 #如果第二条对角线相加,请勾选2 如果(m[0][3]+m[1][2]+m[2][1]+m[3][0]==34): 标志=标志+1 #检查2是否第一条对角线相加 如果(m[0][0]+m[1][1]+m[2][2]+m[3][3]==34): 标志=标志+1 #为了节省资源和提高效率,只有当所有三个检查都返回true时,我们才会添加要检查的行和列。 如果(标志==3): 返回真值 其他: 返回错误 def元素加法器(m): #只有在eligCheck()为给定矩阵返回TRUE后,才能调用此函数。因为满足检查要求的4x4矩阵 #在eligCheck()中,这并不意味着它是一个幻方,我们将每行、每列和两条对角线相加,看看总和是否相等 #等于15。分为两个功能,节省处理能力。 # # #检查所有行的总和是否为15 标志=0 #如果行1相加,则选中1 如果(m[0][0]+m[0][1]+m[0][2]+m[0][3]==34): 标志=标志+1 其他: 返回错误 #如果第2行相加,则选中2 如果(m[1][0]+m[1][1]+m[1][2]+m[1][3]==34): 标志=标志+1 其他: 返回错误 #如果第3行相加,则选中3 如果(m[2][0]+m[2][1]+m[2][2]+m[2][3]==34): 标志=标志+1 其他: 返回错误 #检查第4行是否相加 如果(m[3][0]+m[3][1]+m[3][2]+m[3][3]==34): 标志=标志+1 其他: 返回错误 #如果列1加起来,请勾选4 如果(m[0][0]+m[1][0]+m[2][0]+m[3][0]==34): 标志=标志+1 其他: 返回错误 #如果第2列相加,请勾选5 如果(m[0][1]+m[1][1]+m[2][1]+m[3][1]==34): 标志=标志+1 其他: 返回错误 #如果第3列相加,请勾选6 如果(m[0][2]+m[1][2]+m[2][2]+m[3][2]==34): 标志=标志+1 其他: 返回错误 #如果第4列相加,请勾选7 如果(m[0][3]+m[1][3]+m[2][3]+m[3][3]==34): 标志=标志+1 其他: 返回错误 #请注意,对角线检查已经在eligCheck中验证过()表示从左到右的对角线 #这里的策略是在添加检查之前将标志设置为零,然后逐个运行每个检查。如果 #检查失败,矩阵不是幻方。对于每一个通过的检查,标志都会增加1。因此,在 #所有的检查,如果flag==8,则增加了矩阵是幻方的证明。这一步是多余的,因为程序已经完成 #写入以在遇到失败的检查时立即停止检查,因为幻方的所有检查都必须为真。 如果标志==8: 打印m 返回真值 其他: 打印“****标志错误:elementAdder():第84行***” 打印m def尺寸标尺(n,lst): #此函数用于根据顺序将一维列表转换为二维列表并将其返回#只有平方矩阵。 #n是这里的顺序,lst是一维列表。 i=0 j=0 x=0 #mat=[[]*n表示x范围内的x(n)] mat=[] 对于范围(0,n)内的i: 材料附加([]) 对于范围(0,n)内的j:
如果(j*n+I)成立,但问题是我不能存储集合{1-16}的所有置换。因为这需要16*16*32位内存。:SNo,它不会是16!我们去掉了4个数字,所以它是12!,这仍然很大。所以不要同时处理它们。itertools.permutations返回一个迭代器。不要创建列表,用
for
对置换进行迭代。5亿个循环不会很快,但不是不可能的我应该把我完成的工作放在这里,让其他人看到还是在这里被认为是坏的?所以,不要把角元素设置为静态,我将它们循环……参见CODE,你应该考虑到魔方所满足的方程式,以减少复杂性:使用回溯。有没有更好的方法来做最后一个循环?