好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

123456789组成的3×3的矩阵的行列式最大的值是多少?

123456789怎样运算等于1? - abccsss 的回答
假定每个数字只能出现一次。

回复内容: Mathematica代码

较简洁

 Det/@N@Range@9~Permutations~{9}~ArrayReshape~{9!,3,3}//Max
  


以上用Matlab暴力破解(枚举 种情形),暂未 输出行列式相同的其他情形,貌似基本秒出。

  max_det   =   0  ; 
 init_perm   =   reshape  (  1  :  9  ,   [  3  ,   3  ]); 
 all_perms   =   perms  (  1  :  9  ); 

 for   i   =   1  :  size  (  all_perms  ,   1  ) 
     matrix   =   all_perms  (  i  ,   :); 
     matrix   =   reshape  (  matrix  ,   [  3  ,   3  ]); 
     det_value   =   det  (  matrix  ); 
    
     if   det_value   >   max_det 
         max_det   =   det_value  ; 
         init_perm   =   matrix  ; 
     end 
    
 end 
  
list = Permutations[Range[9], {9}]; list = Permutations[Range[9], {9}];
matrix = Partition[#, 3] & /@ list;
answer = Det /@ matrix;
m = Max[answer];
pos = Flatten[Position[answer, m]];
matrix[[#]] & /@ pos 贴个毫无技术含量暴力程度max的python版。。。

 import itertools
import time

def max_matrix():
	begin = time.time()
	elements = [1, 2, 3, 4, 5, 6, 7, 8, 9]
	maxdet = 0
	maxmat = []
	for i in itertools.permutations(elements, 9):
		det = i[0] * i[4] * i[8] + i[1] * i[5] * i[6] + i[2] * i[3] * i[7] - i[2] * i[4] * i[6] - i[1] * i[3] * i[8] - i[0] * i[5] * i[7]
		if(det > maxdet):
			maxdet = det
			maxmat = []
			for j in range(0, 9):
				maxmat.append(i[j])
	print "|" + str(maxmat[0]) + " " + str(maxmat[1]) + " " + str(maxmat[2]) + "|"
	print "|" + str(maxmat[3]) + " " + str(maxmat[4]) + " " + str(maxmat[5]) + "| = " + str(maxdet)
	print "|" + str(maxmat[6]) + " " + str(maxmat[7]) + " " + str(maxmat[8]) + "|"
	end = time.time()
	print str(end - begin) + 's used.'

if __name__ == '__main__':
	max_matrix()
  
题目应该改成1 2 3 ...n^2组成n阶行列式的最大值。并求最优解的时间复杂度才有意思。 C++:

  #include   
 #include  
 using   namespace   std  ; 
 int   ans  ,   a  []   =   {  1  ,   2  ,   3  ,   4  ,   5  ,   6  ,   7  ,   8  ,   9  }; 
 int   main  ()   { 
   do 
     ans   =   max  (  ans  ,   a  [  0  ]   *   (  a  [  4  ]   *   a  [  8  ]   -   a  [  5  ]   *   a  [  7  ])   + 
                    a  [  1  ]   *   (  a  [  5  ]   *   a  [  6  ]   -   a  [  3  ]   *   a  [  8  ])   + 
                    a  [  2  ]   *   (  a  [  3  ]   *   a  [  7  ]   -   a  [  4  ]   *   a  [  6  ])); 
   while   (  next_permutation  (  a  ,   a   +   9  )); 
   printf  (  "%d  \n  "  ,   ans  ); 
 } 
  
把yellow的答案重排一下可得
9 4 2
3 8 6
5 1 7

很容易看出思路了。
1.所有数按大小在斜率为-1的对角线上依次排开。(即:987在一条对角线,654在一条,321在一条)很容易看出这是让正向数值最大的方法。
2.对于反向的对角线,排除主对角线之外的任意两个数之和相等,且乘积越大的,相应的主对角线元素越小。(也就是让三个乘积的最大值最小,然后最大的结果再和最小的数相配这样)

但是以上方法仅限于1~9的3x3矩阵,对于其它的矩阵不一定适用。
因为显然这种方法要求正向和负向都只有对角线(或平行于对角线),但是4x4的行列式就开始有拐弯了。。。

然后,我感觉还有三个漏洞,一是贪心法不一定保证正向最大,也不一定保证反向最小,更不一定保证正反向之差最大。(不一定都是漏洞,可能有的是恒成立的)
但是我感觉对3x3的非负矩阵来说,贪心在多数情况下是可以拿到最大值的。

PS:试了很多组数,都是这个解,然后又试了一组[1 2 3 4 5 6 7 8 100],显然答案发生了变化,因为100的权值比8和7大太多,所以负向的时候直接就把2和1给了100。那么这也就证明了贪心法确实有时候得不到最大值。 前面已经有了python,c和MMA的代码了,我来一发matlab的吧

  p  =  perms  (  1  :  9  ); 
 [  n  ,  ~  ]=  size  (  p  ); 
 z  =  zeros  (  n  ,  1  ); 
 for   i  =  1  :  n 
     z  (  i  )=  det  (  reshape  (  p  (  i  ,:),  3  ,  3  )); 
 end 
 max  (  z  ) 
 id  =  find  (  z  ==  max  (  z  )); 
 for   i  =  1  :  length  (  id  ) 
     disp  (  reshape  (  p  (  id  (  i  ),:),  3  ,  3  )); 
 end 
  
对于三阶的穷举,可以不用det函数会比较简单:

  p   =   reshape  (  perms  (  1  :  9  ),  ''  ,  3  ,  3  ); 
 M   =   max  (  sum  (  prod  (  p  ,  2  ),  3  )  -  sum  (  prod  (  p  ,  3  ),  2  )); 
  
话题的语言还少个Mathematica,就我来吧
直接9!个结果存下来刚正面,0优化

 Det[Partition[#, 3]] & /@ Permutations[Range[9]] // Max

412
  

查看更多关于123456789组成的3×3的矩阵的行列式最大的值是多少?的详细内容...

  阅读:81次