hustxay 发表于 2006-10-23 22:22

刚学matlab,弱问一下

学了magic函数,感觉功能很强大
以前学C时,想用C实现这个功能,但是没能完成,确实没有找到合适的算法

我查阅了matlab中关于magic的.m文件,然后去掉每一句话的分号(;),
想通过运行过程了解算法,但是发现就用了一些简单的矩阵运算,
我想问:为什么这样简单几步的运算就可以实现呢,其数学根据在哪里?

以下是matlab提供的magic程序(已经去;了),运行前先给n赋值。

n = floor(real(double(n(1))))

% Odd order.
if mod(n,2) == 1
    = meshgrid(1:n)
   A = mod(I+J-(n+3)/2,n)
   B = mod(I+2*J-2,n)
   M = n*A + B + 1

% Doubly even order.
elseif mod(n,4) == 0
    = meshgrid(1:n)
   K = fix(mod(I,4)/2) == fix(mod(J,4)/2)
   M = reshape(1:n*n,n,n)'
   M(K) = n*n+1 - M(K)

% Singly even order.
else
   p = n/2
   M = magic(p)
   M =
   if n == 2, return, end
   i = (1:p)'
   k = (n-2)/4
   j =
   M(,j) = M(,j)
   i = k+1
   j =
   M(,j) = M(,j)
end

happy 发表于 2006-10-24 10:58

魔术方阵可依N值为奇数或偶数分为奇数魔术方阵与偶数魔术方阵,洛书
是奇数魔术方阵中最简单的一型.後者又可依N/2为奇数或偶数,再分为倍偶数
与单偶数魔术方阵.

1. 奇数魔术方阵

当mod(N,2)==1成立时,

A B C
D E F
G H I
数学法求解:
A+B+C=15, D+E+F=15, G+H+I=15, A+D+G=15, B+E+H=15, C+F+I=15,
A+E+I=15, C+E+G=15, 总共九个未知数,八个方程式.
提示:E=5.其中一组答案如下,正是洛书的数学表示法:

4 9 2
3 5 7
8 1 6

基於方阵可以旋转而不会改变各列,各栏之和,所以同顺序的正确答案尚
有其他三个方阵.另外,上下两列对调,左右两栏对调,均不影响答案的正确性.
所以真正的组合不只此处列出的四组.


8 3 4
1 5 9
6 7 2


6 1 8
7 5 3
2 9 4


2 7 6
9 5 1
4 3 8

求解奇数魔术方阵的步骤:

1. 由首列中间格开始填入1 2. 朝右上方向,依序填入,
3. 假设最上格与最下格相连 4. 假设最右格与最左格相连
5. 右上格已填满时,填入原格下一列.


8 1 6
3 5 7
4 9 2

Magic(5), 各列和=各行和=各对角线和=65
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9

MATLAB程式解法

= meshgrid(1:n);
A = mod(I+J-(n+3)/2,n); B = mod(I+2*J-2,n);
M = n*A + B + 1;


2. 倍偶数魔术方阵
N除以 2为偶数者(当mod(N,4)==0成立)为倍偶数(doubly even)方阵.

做法:
1. 由左上至右下,依序填入1-16,对角线上各格不填.
2. 由右下至左上,依序填入1-16,只填对角线上各格.

2 3 16 2 3 13
5 8 5 11 10 8
9 12 9 7 6 12
14 15 4 14 15 1
Magic(4) 各列和=各行和=各对角线和=34

3. 当方阵数大於4且为4的倍数时,以4x4为单元,绘出对角线,其他步骤
同步骤1与2.

2 3 6 7
9 12 13 16
17 20 21 24
26 27 30 31
34 35 38 39
41 4445 48
49 5253 56
58 59 62 63

64 2 3 61606 7 57
9 55 5412 13515016
17 47 4620 21434224
40 26 27373630 3133
32 34 35292838 3925
41 23 224445191848
49 15 145253111056
8 58 595 4 62 631
Magic(8) , 各列和=各行和=各对角线和= 260

MATLAB程式解法

= meshgrid(1:n);
K = fix(mod(I,4)/2) == fix(mod(J,4)/2);
M = reshape(1:n*n,n,n)';
M(K) = n*n+1 - M(K);


3. 单偶数魔术方阵

N除以 2为奇数者(当mod(N,4)0且mode(N,2)=0成立时),称为单偶数
(single even)方阵.

做法:

步骤1. 将N/2 得p,首先求出p的奇数方阵.
步骤2. 将N x N 的单偶数方阵分为4区,各区以p的奇数方阵建立.建法为:
A区为p的奇数方阵,B区为A区各格之值加上1*p^2之值,C区为A
区各格之值加上2*p^2之值,D区为A区各格之值加上3*p^2之值.A
区位於左上,B区位於右下, C区位於右上,D区位於左下.

A C
D B

以6x6 单偶数方阵为例:
8 1 6 26 19 24
3 5 7 21 23 25
4 9 2 22 27 20
35 28 33 17 10 15
30 3234 12 14 16
31 36 29 13 18 11

步骤3. 将左侧A,D两区黄色各格对调.左侧需交换的黄色栏数为1至k(=
(N-2)/4)加上两个对角线交叉点,其中与後者同列的第一栏那格可免交
换.速记:k代表A区对角线交叉点以左的总栏数.

当 N=6, k=1:

35 1 6 26 19 24
3 327 21 23 25
31 9 2 22 27 20
8 28 33 17 10 15
30 5 34 12 14 16
4 36 29 13 18 11
Magic(6) , 各列和=各行和=各对角线和=111

当N=10时,步骤1,2可完成以下10x10方阵,当N=10, k=2, 左侧黄色
区亦标示如下:

1724 1 8 15 67 74 51 5865
235 7 14 16 73 55 57 6466
4 6 13 20 22 54 56 63 7072
1012 19 21 3 60 62 69 7153
1118 25 2 9 61 68 75 5259
9299 76 83 90 42 49 26 3340
9880 82 89 91 48 30 32 3941
7981 88 95 97 29 31 38 4547
8587 94 96 78 35 37 44 4628
8693 100 77 84 36 43 50 2734

步骤4. 将右侧B,C两区绿色各格对调,即可完成.右侧需交换的绿色栏号为右
数(k-1)栏,当N=6时,k=1,右侧无需交换的栏位,当N=10时,k=2,
只有右数第1栏需交换.如上表所示.交换结果如下:

9299 1 8 15 67 74 51 5840
9880 7 14 16 73 55 57 6441
4 81 88 20 22 54 56 63 7047
8587 19 21 3 60 62 69 7128
8693 25 2 9 61 68 75 5234
1724 76 83 90 42 49 26 3365
235 82 89 91 48 30 32 3966
796 13 95 97 29 31 38 4572
1012 94 96 78 35 37 44 4653
1118 100 77 84 36 43 50 2759
Magic(10) , 各列和=各行和=各对角线和=505

以14x14 单偶数方阵为例:
当N=14时,步骤1,2可完成以下14x14方阵:

30 3948 1 10 19 28 128 137 14699108117 126
38 477 9 18 27 29 136 145 105 107 116125 127
46 68 17 26 35 37 144 104 106 115 124133 135
5 1416 25 34 36 45 103 112 114 123 132134 143
13 1524 33 42 44 4 111 113 122 131 140142 102
21 2332 41 43 3 12 119 121 130 139 141101 110
22 3140 49 2 11 20 120 129 138 147 100109 118
177 186195 148 157 166 175 79 88 97505968 77
185 194154 156 165 174 176 87 96 56 58 6776 78
193 153155 164 173 182 184 95 55 57 66 7584 86
152 161163 172 181 183 192 54 63 65 74 8385 94
160 162171 180 189 191 151 62 64 73 82 9193 53
168 170179 188 190 150 159 70 72 81 90 9252 61
169 178187 196 149 158 167 71 80 89 98 5160 69

当N=14时,k=3,代表储左侧对角线交叉点之外,左侧3栏,右侧2栏
需交换.结果如下表:

177 186195 1 10 19 28 128 137 1469910868 77
185 194154 9 18 27 29 136 145 105 107 11676 78
193 153155 17 26 35 37 144 104 106 115 12484 86
5 161163 172 34 36 45 103 112 114 123 13285 94
160 162171 33 42 44 4 111 113 122 131 14093 53
168 170179 41 43 3 12 119 121 130 139 14152 61
169 178187 49 2 11 20 120 129 138 147 10060 69
30 3948 148 157 166 175 79 88 975059117 126
38 477 156 165 174 176 87 96 56 58 67125 127
46 68 164 173 182 184 95 55 57 66 75133 135
152 1416 25 181 183 192 54 63 65 74 83134 143
13 1524 180 189 191 151 62 64 73 82 91142 102
21 2332 188 190 150 159 70 72 81 90 92101 110
22 3140 196 149 158 167 71 80 89 98 51109 118
Magic(14), 各列和=各行和=各对角线和=1379

MATLAB程式解法

p = n/2; M = magic(p);
M = ;
if n == 2, break, end
i = (1:p)'; k = (n-2)/4; j = ;
M(,j) = M(,j);
i = k+1; j = ; M(,j) = M(,j)

hustxay 发表于 2006-10-25 10:23

谢谢

以上很详细地提供了各种N值的填入方法

按照以上规则填入的确可以满足magic的规则

q214468952 发表于 2006-10-27 21:50

happy还是一个数学高手呢。更钦佩 楼主的学风哦。钦佩钦佩
页: [1]
查看完整版本: 刚学matlab,弱问一下