假定每个数字只能出现一次。
回复内容:
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 endlist = 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的矩阵的行列式最大的值是多少?的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did83234